replace "== None" with "is None" and "!= None" with "is not None" Cc: Yonghong Zhu <yonghong.zhu@intel.com> Cc: Liming Gao <liming.gao@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Jaben Carsey <jaben.carsey@intel.com> Reviewed-by: Yonghong Zhu <yonghong.zhu@intel.com>
		
			
				
	
	
		
			326 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			326 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
## @file
 | 
						|
# This file implements the log mechanism for Python tools.
 | 
						|
#
 | 
						|
# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
 | 
						|
#
 | 
						|
# This program and the accompanying materials are licensed and made available 
 | 
						|
# under the terms and conditions of the BSD License which accompanies this 
 | 
						|
# distribution. The full text of the license may be found at 
 | 
						|
# http://opensource.org/licenses/bsd-license.php
 | 
						|
#
 | 
						|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | 
						|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
						|
#
 | 
						|
 | 
						|
'''
 | 
						|
Logger
 | 
						|
'''
 | 
						|
 | 
						|
## Import modules
 | 
						|
from sys import argv
 | 
						|
from sys import stdout
 | 
						|
from sys import stderr
 | 
						|
import os.path
 | 
						|
from os import remove
 | 
						|
from logging import getLogger
 | 
						|
from logging import Formatter
 | 
						|
from logging import StreamHandler
 | 
						|
from logging import FileHandler
 | 
						|
from traceback import extract_stack
 | 
						|
 | 
						|
from Logger.ToolError import FatalError
 | 
						|
from Logger.ToolError import WARNING_AS_ERROR
 | 
						|
from Logger.ToolError import gERROR_MESSAGE
 | 
						|
from Logger.ToolError import UNKNOWN_ERROR
 | 
						|
from Library import GlobalData
 | 
						|
 | 
						|
#
 | 
						|
# Log level constants
 | 
						|
#
 | 
						|
DEBUG_0 = 1
 | 
						|
DEBUG_1 = 2
 | 
						|
DEBUG_2 = 3
 | 
						|
DEBUG_3 = 4
 | 
						|
DEBUG_4 = 5
 | 
						|
DEBUG_5 = 6
 | 
						|
DEBUG_6 = 7
 | 
						|
DEBUG_7 = 8
 | 
						|
DEBUG_8 = 9
 | 
						|
DEBUG_9 = 10
 | 
						|
VERBOSE = 15
 | 
						|
INFO    = 20
 | 
						|
WARN    = 30
 | 
						|
QUIET   = 40
 | 
						|
QUIET_1 = 41
 | 
						|
ERROR   = 50
 | 
						|
SILENT  = 60
 | 
						|
 | 
						|
IS_RAISE_ERROR = True
 | 
						|
SUPRESS_ERROR = False
 | 
						|
 | 
						|
#
 | 
						|
# Tool name
 | 
						|
#
 | 
						|
_TOOL_NAME = os.path.basename(argv[0])
 | 
						|
#
 | 
						|
# For validation purpose
 | 
						|
#
 | 
						|
_LOG_LEVELS = [DEBUG_0, DEBUG_1, DEBUG_2, DEBUG_3, DEBUG_4, DEBUG_5, DEBUG_6, \
 | 
						|
              DEBUG_7, DEBUG_8, DEBUG_9, VERBOSE, WARN, INFO, ERROR, QUIET, \
 | 
						|
              QUIET_1, SILENT]
 | 
						|
#
 | 
						|
# For DEBUG level (All DEBUG_0~9 are applicable)
 | 
						|
#
 | 
						|
_DEBUG_LOGGER = getLogger("tool_debug")
 | 
						|
_DEBUG_FORMATTER = Formatter("[%(asctime)s.%(msecs)d]: %(message)s", \
 | 
						|
                            datefmt="%H:%M:%S")
 | 
						|
#
 | 
						|
# For VERBOSE, INFO, WARN level
 | 
						|
#
 | 
						|
_INFO_LOGGER = getLogger("tool_info")
 | 
						|
_INFO_FORMATTER = Formatter("%(message)s")
 | 
						|
#
 | 
						|
# For ERROR level
 | 
						|
#
 | 
						|
_ERROR_LOGGER = getLogger("tool_error")
 | 
						|
_ERROR_FORMATTER = Formatter("%(message)s")
 | 
						|
 | 
						|
#
 | 
						|
# String templates for ERROR/WARN/DEBUG log message
 | 
						|
#
 | 
						|
_ERROR_MESSAGE_TEMPLATE = \
 | 
						|
('\n\n%(tool)s...\n%(file)s(%(line)s): error %(errorcode)04X: %(msg)s\n\t%(extra)s')
 | 
						|
 | 
						|
__ERROR_MESSAGE_TEMPLATE_WITHOUT_FILE = \
 | 
						|
'\n\n%(tool)s...\n : error %(errorcode)04X: %(msg)s\n\t%(extra)s'
 | 
						|
 | 
						|
_WARNING_MESSAGE_TEMPLATE = '%(tool)s...\n%(file)s(%(line)s): warning: %(msg)s'
 | 
						|
_WARNING_MESSAGE_TEMPLATE_WITHOUT_FILE = '%(tool)s: : warning: %(msg)s'
 | 
						|
_DEBUG_MESSAGE_TEMPLATE = '%(file)s(%(line)s): debug: \n    %(msg)s'
 | 
						|
 | 
						|
 | 
						|
#
 | 
						|
# Log INFO message
 | 
						|
#
 | 
						|
#Info    = _INFO_LOGGER.info
 | 
						|
 | 
						|
def Info(msg, *args, **kwargs):
 | 
						|
    _INFO_LOGGER.info(msg, *args, **kwargs)
 | 
						|
 | 
						|
#
 | 
						|
# Log information which should be always put out
 | 
						|
#
 | 
						|
def Quiet(msg, *args, **kwargs):
 | 
						|
    _ERROR_LOGGER.error(msg, *args, **kwargs)
 | 
						|
 | 
						|
## Log debug message
 | 
						|
#
 | 
						|
#   @param  Level       DEBUG level (DEBUG0~9)
 | 
						|
#   @param  Message     Debug information
 | 
						|
#   @param  ExtraData   More information associated with "Message"
 | 
						|
#
 | 
						|
def Debug(Level, Message, ExtraData=None):
 | 
						|
    if _DEBUG_LOGGER.level > Level:
 | 
						|
        return
 | 
						|
    if Level > DEBUG_9:
 | 
						|
        return
 | 
						|
    #
 | 
						|
    # Find out the caller method information
 | 
						|
    #
 | 
						|
    CallerStack = extract_stack()[-2]
 | 
						|
    TemplateDict = {
 | 
						|
        "file"      : CallerStack[0],
 | 
						|
        "line"      : CallerStack[1],
 | 
						|
        "msg"       : Message,
 | 
						|
    }
 | 
						|
 | 
						|
    if ExtraData is not None:
 | 
						|
        LogText = _DEBUG_MESSAGE_TEMPLATE % TemplateDict + "\n    %s" % ExtraData
 | 
						|
    else:
 | 
						|
        LogText = _DEBUG_MESSAGE_TEMPLATE % TemplateDict
 | 
						|
 | 
						|
    _DEBUG_LOGGER.log(Level, LogText)
 | 
						|
 | 
						|
## Log verbose message
 | 
						|
#
 | 
						|
#   @param  Message     Verbose information
 | 
						|
#
 | 
						|
def Verbose(Message):
 | 
						|
    return _INFO_LOGGER.log(VERBOSE, Message)
 | 
						|
 | 
						|
## Log warning message
 | 
						|
#
 | 
						|
#   Warning messages are those which might be wrong but won't fail the tool.
 | 
						|
#
 | 
						|
#   @param  ToolName    The name of the tool. If not given, the name of caller
 | 
						|
#                       method will be used.
 | 
						|
#   @param  Message     Warning information
 | 
						|
#   @param  File        The name of file which caused the warning.
 | 
						|
#   @param  Line        The line number in the "File" which caused the warning.
 | 
						|
#   @param  ExtraData   More information associated with "Message"
 | 
						|
#
 | 
						|
def Warn(ToolName, Message, File=None, Line=None, ExtraData=None):
 | 
						|
    if _INFO_LOGGER.level > WARN:
 | 
						|
        return
 | 
						|
    #
 | 
						|
    # if no tool name given, use caller's source file name as tool name
 | 
						|
    #
 | 
						|
    if ToolName is None or ToolName == "":
 | 
						|
        ToolName = os.path.basename(extract_stack()[-2][0])
 | 
						|
 | 
						|
    if Line is None:
 | 
						|
        Line = "..."
 | 
						|
    else:
 | 
						|
        Line = "%d" % Line
 | 
						|
 | 
						|
    TemplateDict = {
 | 
						|
        "tool"      : ToolName,
 | 
						|
        "file"      : File,
 | 
						|
        "line"      : Line,
 | 
						|
        "msg"       : Message,
 | 
						|
    }
 | 
						|
 | 
						|
    if File is not None:
 | 
						|
        LogText = _WARNING_MESSAGE_TEMPLATE % TemplateDict
 | 
						|
    else:
 | 
						|
        LogText = _WARNING_MESSAGE_TEMPLATE_WITHOUT_FILE % TemplateDict
 | 
						|
 | 
						|
    if ExtraData is not None:
 | 
						|
        LogText += "\n    %s" % ExtraData
 | 
						|
 | 
						|
    _INFO_LOGGER.log(WARN, LogText)
 | 
						|
    #
 | 
						|
    # Raise an execption if indicated
 | 
						|
    #
 | 
						|
    if GlobalData.gWARNING_AS_ERROR == True:
 | 
						|
        raise FatalError(WARNING_AS_ERROR)
 | 
						|
 | 
						|
## Log ERROR message
 | 
						|
#
 | 
						|
# Once an error messages is logged, the tool's execution will be broken by 
 | 
						|
# raising an execption. If you don't want to break the execution later, you 
 | 
						|
# can give "RaiseError" with "False" value.
 | 
						|
#
 | 
						|
#   @param  ToolName    The name of the tool. If not given, the name of caller
 | 
						|
#                       method will be used.
 | 
						|
#   @param  ErrorCode   The error code
 | 
						|
#   @param  Message     Warning information
 | 
						|
#   @param  File        The name of file which caused the error.
 | 
						|
#   @param  Line        The line number in the "File" which caused the warning.
 | 
						|
#   @param  ExtraData   More information associated with "Message"
 | 
						|
#   @param  RaiseError  Raise an exception to break the tool's executuion if
 | 
						|
#                       it's True. This is the default behavior.
 | 
						|
#
 | 
						|
def Error(ToolName, ErrorCode, Message=None, File=None, Line=None, \
 | 
						|
          ExtraData=None, RaiseError=IS_RAISE_ERROR):
 | 
						|
    if ToolName:
 | 
						|
        pass
 | 
						|
    if Line is None:
 | 
						|
        Line = "..."
 | 
						|
    else:
 | 
						|
        Line = "%d" % Line
 | 
						|
 | 
						|
    if Message is None:
 | 
						|
        if ErrorCode in gERROR_MESSAGE:
 | 
						|
            Message = gERROR_MESSAGE[ErrorCode]
 | 
						|
        else:
 | 
						|
            Message = gERROR_MESSAGE[UNKNOWN_ERROR]
 | 
						|
 | 
						|
    if ExtraData is None:
 | 
						|
        ExtraData = ""
 | 
						|
 | 
						|
    TemplateDict = {
 | 
						|
        "tool"      : _TOOL_NAME,
 | 
						|
        "file"      : File,
 | 
						|
        "line"      : Line,
 | 
						|
        "errorcode" : ErrorCode,
 | 
						|
        "msg"       : Message,
 | 
						|
        "extra"     : ExtraData
 | 
						|
    }
 | 
						|
 | 
						|
    if File is not None:
 | 
						|
        LogText =  _ERROR_MESSAGE_TEMPLATE % TemplateDict
 | 
						|
    else:
 | 
						|
        LogText = __ERROR_MESSAGE_TEMPLATE_WITHOUT_FILE % TemplateDict
 | 
						|
 | 
						|
    if not SUPRESS_ERROR:
 | 
						|
        _ERROR_LOGGER.log(ERROR, LogText)
 | 
						|
    if RaiseError:
 | 
						|
        raise FatalError(ErrorCode)
 | 
						|
 | 
						|
    
 | 
						|
## Initialize log system
 | 
						|
#
 | 
						|
def Initialize():
 | 
						|
    #
 | 
						|
    # Since we use different format to log different levels of message into 
 | 
						|
    # different place (stdout or stderr), we have to use different "Logger" 
 | 
						|
    # objects to do this.
 | 
						|
    #
 | 
						|
    # For DEBUG level (All DEBUG_0~9 are applicable)
 | 
						|
    _DEBUG_LOGGER.setLevel(INFO)
 | 
						|
    _DebugChannel = StreamHandler(stdout)
 | 
						|
    _DebugChannel.setFormatter(_DEBUG_FORMATTER)
 | 
						|
    _DEBUG_LOGGER.addHandler(_DebugChannel)
 | 
						|
    #
 | 
						|
    # For VERBOSE, INFO, WARN level
 | 
						|
    #
 | 
						|
    _INFO_LOGGER.setLevel(INFO)
 | 
						|
    _InfoChannel = StreamHandler(stdout)
 | 
						|
    _InfoChannel.setFormatter(_INFO_FORMATTER)
 | 
						|
    _INFO_LOGGER.addHandler(_InfoChannel)
 | 
						|
    #
 | 
						|
    # For ERROR level
 | 
						|
    #
 | 
						|
    _ERROR_LOGGER.setLevel(INFO)
 | 
						|
    _ErrorCh = StreamHandler(stderr)
 | 
						|
    _ErrorCh.setFormatter(_ERROR_FORMATTER)
 | 
						|
    _ERROR_LOGGER.addHandler(_ErrorCh)
 | 
						|
 | 
						|
 | 
						|
## Set log level
 | 
						|
#
 | 
						|
#   @param  Level   One of log level in _LogLevel
 | 
						|
#
 | 
						|
def SetLevel(Level):
 | 
						|
    if Level not in _LOG_LEVELS:
 | 
						|
        Info("Not supported log level (%d). Use default level instead." % \
 | 
						|
             Level)
 | 
						|
        Level = INFO
 | 
						|
    _DEBUG_LOGGER.setLevel(Level)
 | 
						|
    _INFO_LOGGER.setLevel(Level)
 | 
						|
    _ERROR_LOGGER.setLevel(Level)
 | 
						|
 | 
						|
## Get current log level
 | 
						|
#
 | 
						|
def GetLevel():
 | 
						|
    return _INFO_LOGGER.getEffectiveLevel()
 | 
						|
 | 
						|
## Raise up warning as error
 | 
						|
#
 | 
						|
def SetWarningAsError():
 | 
						|
    GlobalData.gWARNING_AS_ERROR = True
 | 
						|
 | 
						|
## Specify a file to store the log message as well as put on console
 | 
						|
#
 | 
						|
#   @param  LogFile     The file path used to store the log message
 | 
						|
#
 | 
						|
def SetLogFile(LogFile):
 | 
						|
    if os.path.exists(LogFile):
 | 
						|
        remove(LogFile)
 | 
						|
 | 
						|
    _Ch = FileHandler(LogFile)
 | 
						|
    _Ch.setFormatter(_DEBUG_FORMATTER)
 | 
						|
    _DEBUG_LOGGER.addHandler(_Ch)
 | 
						|
 | 
						|
    _Ch = FileHandler(LogFile)
 | 
						|
    _Ch.setFormatter(_INFO_FORMATTER)
 | 
						|
    _INFO_LOGGER.addHandler(_Ch)
 | 
						|
 | 
						|
    _Ch = FileHandler(LogFile)
 | 
						|
    _Ch.setFormatter(_ERROR_FORMATTER)
 | 
						|
    _ERROR_LOGGER.addHandler(_Ch)
 | 
						|
 | 
						|
 | 
						|
 |