00001 """
00002 see log class
00003 """
00004
00005 __copyright__ = """
00006 Copyright 2008 Sean Ross-Ross
00007 """
00008 __license__ = """
00009 This file is part of SLIMpy .
00010
00011 SLIMpy is free software: you can redistribute it and/or modify
00012 it under the terms of the GNU Lesser General Public License as published by
00013 the Free Software Foundation, either version 3 of the License, or
00014 (at your option) any later version.
00015
00016 SLIMpy is distributed in the hope that it will be useful,
00017 but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00019 GNU Lesser General Public License for more details.
00020
00021 You should have received a copy of the GNU Lesser General Public License
00022 along with SLIMpy . If not, see <http://www.gnu.org/licenses/>.
00023 """
00024
00025
00026 from sys import stderr,stdout
00027 from os.path import devnull
00028 from slimpy_base.Environment.InstanceManager import InstanceManager
00029
00030 NULLOUT = open( devnull, 'w' )
00031
00032 class _Log( object ):
00033 """
00034 log object is used by all of slimpy to coordinate output
00035 suggested use:
00036 alog = log()
00037 print >>alog, "logging somthing"
00038 to print unconditionally or:
00039 print >>alog(3), "logging somthing"
00040 to print only of verbosity is above 3
00041
00042 """
00043
00044 name = "log"
00045 env = InstanceManager()
00046 __shared_state = {}
00047
00048
00049 def __init__( self ):
00050 """
00051 singleton instance
00052 """
00053 self.__dict__ = self.__shared_state
00054
00055
00056 def init( self, lfile=stderr, nullout=NULLOUT, verbose = 1 ):
00057 """
00058 init is for internal use only. use setter funtions to promote
00059 consistancy.
00060 """
00061 self.verbose = verbose
00062 self.setLogFile( lfile )
00063 self.setNullOut( nullout )
00064
00065 def setVerbose( self, verb ):
00066 """
00067 set verbosity level
00068 """
00069 self.verbose = verb
00070
00071 def setLogFile( self, lfile ):
00072 """
00073 @param:lfile must have a write method
00074 """
00075 if isinstance( lfile, str ):
00076 if lfile == "stdout":
00077 lfile = stdout
00078 elif lfile == "stderr":
00079 lfile = stderr
00080 elif lfile == 'null':
00081 lfile = NULLOUT
00082 else:
00083 lfile = open( lfile, 'w' )
00084 assert hasattr( lfile, 'write' ), "lfile object: %(lfile)s must have a write method " %vars()
00085
00086 self.logFile = lfile
00087
00088 def setNullOut( self, no ):
00089 """
00090 set where the null out points to
00091 this is so the log can discriminate what output it will print
00092 """
00093 if isinstance( no, str ):
00094 no = open( no, 'w' )
00095 assert hasattr( no, 'write' ), "no object: %(no) must have a write method " %( vars() )
00096
00097 self.nullOut = no
00098
00099 def write( self, string ):
00100 """
00101 write to file
00102 """
00103 slimvars = self.env['slimvars']
00104
00105 string = str( string )
00106 if slimvars['abridge']:
00107 string = self.abridge( string )
00108 self.logFile.write( string )
00109 self.logFile.flush()
00110
00111 def get_slimvars(self):
00112 slimvars = self.env['slimvars']
00113
00114 logfile = slimvars['logfile']
00115
00116 if not isinstance(logfile, dict):
00117 self.setLogFile( logfile )
00118 slimvars['logfile'] = { }
00119
00120 logfile = slimvars['logfile']
00121
00122 logfile.setdefault('log', self)
00123 logfile.setdefault('null', NULLOUT )
00124
00125 return logfile,slimvars['debug']
00126
00127 def set_default_log(self ,verb,logname):
00128
00129 logfile,debug = self.get_slimvars()
00130
00131 has_key = logfile.has_key(logname)
00132 if not has_key:
00133 if isinstance(debug, (list,tuple) ):
00134 debug_log = logname in debug
00135 else:
00136 debug_log = logname == debug
00137
00138 if verb or debug_log:
00139 logname = 'log'
00140 else:
00141 logname = 'null'
00142
00143 logfile[logname] = self.log_open( logfile[logname] )
00144 return logfile[logname]
00145
00146
00147 def log_open(self,logname):
00148 if isinstance(logname, file):
00149 return logname
00150 elif isinstance(logname, _log):
00151 return logname
00152 elif logname == "stdout":
00153 return stdout
00154 elif logname == "stderr":
00155 return stderr
00156 elif logname == 'null':
00157 return NULLOUT
00158 else:
00159 return open( logname, 'w' )
00160
00161
00162
00163 def __call__( self, lval, debug=None ):
00164 """
00165 used like print >> log(3,'solver')
00166 which will print if the current verbosity is greater than or eual to
00167 3 or the debug variable is set to 'solver'
00168 """
00169 slimvars = self.env['slimvars']
00170
00171 verb = slimvars['verbose'] >= lval
00172
00173
00174
00175
00176
00177
00178 if debug:
00179 log = self.set_default_log( verb, debug )
00180 elif verb:
00181 log = self.set_default_log(verb, 'log')
00182 else:
00183 log = self.set_default_log(verb, 'null')
00184
00185
00186
00187
00188
00189 return log
00190
00191
00192
00193
00194
00195 def abridge( self, string ):
00196 """
00197 uses the global dict variable 'abridgeMap' in SLIMGlobals
00198 to replace all of the ocurrences of each key with the value
00199 this is helpful in reducing the amount of garbage input
00200 for examle in the simple1 tutorial I replace each $RSFROOT path with ''
00201
00202 """
00203 slimvars = self.env['slimvars']
00204
00205 for item in slimvars['abridgeMap'].items():
00206 string = string.replace( *item )
00207
00208 return string
00209
00210
00211 _log = _Log