fix possible IOError (pemission denied) 2 users are writing to the same log file
[sfa.git] / sfa / util / sfalogging.py
index b4a1290..199066d 100755 (executable)
@@ -15,24 +15,41 @@ class _SfaLogger:
     def __init__ (self,logfile=None,loggername=None,level=logging.INFO):
         # default is to locate loggername from the logfile if avail.
         if not logfile:
-            loggername='console'
-            handler=logging.StreamHandler()
-            handler.setFormatter(logging.Formatter("%(levelname)s %(message)s"))
-        else:
-            if not loggername:
-                loggername=os.path.basename(logfile)
-            try:
-                handler=logging.handlers.RotatingFileHandler(logfile,maxBytes=1000000, backupCount=5) 
-            except IOError:
-                # This is usually a permissions error becaue the file is
-                # owned by root, but httpd is trying to access it.
-                tmplogfile=os.getenv("TMPDIR", "/tmp") + os.path.sep + os.path.basename(logfile)
-                handler=logging.handlers.RotatingFileHandler(tmplogfile,maxBytes=1000000, backupCount=5) 
-            handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s"))
-
+            #loggername='console'
+            #handler=logging.StreamHandler()
+            #handler.setFormatter(logging.Formatter("%(levelname)s %(message)s"))
+            logfile = "/var/log/sfa.log"
+
+        if not loggername:
+            loggername=os.path.basename(logfile)
+        try:
+            handler=logging.handlers.RotatingFileHandler(logfile,maxBytes=1000000, backupCount=5) 
+        except IOError:
+            # This is usually a permissions error becaue the file is
+            # owned by root, but httpd is trying to access it.
+            tmplogfile=os.getenv("TMPDIR", "/tmp") + os.path.sep + os.path.basename(logfile)
+            # In strange uses, 2 users on same machine might use same code,
+            # meaning they would clobber each others files
+            # We could (a) rename the tmplogfile, or (b)
+            # just log to the console in that case.
+            # Here we default to the console.
+            if os.path.exists(tmplogfile) and not os.access(tmplogfile,os.W_OK):
+                loggername = loggername + "-console"
+                handler = logging.StreamHandler()
+            handler=logging.handlers.RotatingFileHandler(tmplogfile,maxBytes=1000000, backupCount=5) 
+        handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s"))
         self.logger=logging.getLogger(loggername)
         self.logger.setLevel(level)
-        self.logger.addHandler(handler)
+        # check if logger already has the handler we're about to add
+        handler_exists = False
+        for l_handler in self.logger.handlers:
+            if l_handler.baseFilename == handler.baseFilename and \
+               l_handler.level == handler.level:
+                handler_exists = True 
+
+        if not handler_exists:
+            self.logger.addHandler(handler)
+
         self.loggername=loggername
 
     def setLevel(self,level):
@@ -84,31 +101,20 @@ class _SfaLogger:
         self.debug("%s BEG STACK"%message+"\n"+to_log)
         self.debug("%s END STACK"%message)
 
-####################
-# import-related operations go in this file
-_import_logger=_SfaLogger(logfile='/var/log/sfa_import.log')
-# servers log into /var/log/sfa.log
-_server_logger=_SfaLogger(logfile='/var/log/sfa.log')
-## clients use the console
-#_console_logger=_SfaLogger()
-
-# default is to use the server-side logger
-#_the_logger=_server_logger
-
-# clients would change the default by issuing one of these call
-#def sfa_logger_goes_to_console():
-#    current_module=sys.modules[globals()['__name__']]
-#    current_module._the_logger=_console_logger
-#
-# clients would change the default by issuing one of these call
-#def sfa_logger_goes_to_import():
-#    current_module=sys.modules[globals()['__name__']]
-#    current_module._the_logger=_import_logger
-
-# this is how to retrieve the 'right' logger
-def sfa_logger():
-    return _server_logger
+    def enable_console(self, stream=sys.stdout):
+        formatter = logging.Formatter("%(message)s")
+        handler = logging.StreamHandler(stream)
+        handler.setFormatter(formatter)
+        self.logger.addHandler(handler)
 
+
+info_logger = _SfaLogger(loggername='info', level=logging.INFO)
+debug_logger = _SfaLogger(loggername='debug', level=logging.DEBUG)
+warn_logger = _SfaLogger(loggername='warning', level=logging.WARNING)
+error_logger = _SfaLogger(loggername='error', level=logging.ERROR)
+critical_logger = _SfaLogger(loggername='critical', level=logging.CRITICAL)
+logger = info_logger
+sfi_logger = _SfaLogger(logfile=os.path.expanduser("~/.sfi/")+'sfi.log',loggername='sfilog', level=logging.DEBUG)
 ########################################
 import time
 
@@ -137,24 +143,25 @@ def profile(logger):
 if __name__ == '__main__': 
     print 'testing sfalogging into logger.log'
     logger=_SfaLogger('logger.log')
+    logger2=_SfaLogger('logger.log', level=logging.DEBUG)
+    logger3=_SfaLogger('logger.log', level=logging.ERROR)
+    print logger.logger.handlers
+   
     logger.critical("logger.critical")
     logger.error("logger.error")
-    logger.warning("logger.warning")
+    logger.warn("logger.warning")
     logger.info("logger.info")
     logger.debug("logger.debug")
     logger.setLevel(logging.DEBUG)
     logger.debug("logger.debug again")
     
-    #sfa_logger_goes_to_console()
-    my_logger=sfa_logger()
-    my_logger.info("redirected to console")
 
-    @profile(my_logger)
+    @profile(logger)
     def sleep(seconds = 1):
         time.sleep(seconds)
 
-    my_logger.info('console.info')
+    logger.info('console.info')
     sleep(0.5)
-    my_logger.setLevel(logging.DEBUG)
+    logger.setLevel(logging.DEBUG)
     sleep(0.25)