203 lines
6.2 KiB
Python
203 lines
6.2 KiB
Python
# -*- coding: utf-8 -*-
|
|
# ***************************************************************************
|
|
# * Copyright (c) 2016 sliptonic <shopinthewoods@gmail.com> *
|
|
# * *
|
|
# * This program is free software; you can redistribute it and/or modify *
|
|
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
|
# * as published by the Free Software Foundation; either version 2 of *
|
|
# * the License, or (at your option) any later version. *
|
|
# * for detail see the LICENCE text file. *
|
|
# * *
|
|
# * This program is distributed in the hope that it will be useful, *
|
|
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
# * GNU Library General Public License for more details. *
|
|
# * *
|
|
# * You should have received a copy of the GNU Library General Public *
|
|
# * License along with this program; if not, write to the Free Software *
|
|
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
|
# * USA *
|
|
# * *
|
|
# ***************************************************************************
|
|
|
|
import FreeCAD
|
|
import os
|
|
import traceback
|
|
|
|
|
|
class Level:
|
|
"""Enumeration of log levels, used for setLevel and getLevel."""
|
|
|
|
RESET = -1
|
|
ERROR = 0
|
|
WARNING = 1
|
|
NOTICE = 2
|
|
INFO = 3
|
|
DEBUG = 4
|
|
|
|
_names = {
|
|
ERROR: "ERROR",
|
|
WARNING: "WARNING",
|
|
NOTICE: "NOTICE",
|
|
INFO: "INFO",
|
|
DEBUG: "DEBUG",
|
|
}
|
|
|
|
@classmethod
|
|
def toString(cls, level):
|
|
return cls._names.get(level, "UNKNOWN")
|
|
|
|
|
|
_defaultLogLevel = Level.NOTICE
|
|
_moduleLogLevel = {}
|
|
_useConsole = True
|
|
_trackModule = {}
|
|
_trackAll = False
|
|
|
|
|
|
def logToConsole(yes):
|
|
"""(boolean) - if set to True (default behaviour) log messages are printed to the console. Otherwise they are printed to stdout."""
|
|
global _useConsole
|
|
_useConsole = yes
|
|
|
|
|
|
def setLevel(level, module=None):
|
|
"""(level, module = None)
|
|
if no module is specified the default log level is set.
|
|
Otherwise the module specific log level is changed (use RESET to clear)."""
|
|
global _defaultLogLevel
|
|
global _moduleLogLevel
|
|
if module:
|
|
if level == Level.RESET:
|
|
if _moduleLogLevel.get(module, -1) != -1:
|
|
del _moduleLogLevel[module]
|
|
else:
|
|
_moduleLogLevel[module] = level
|
|
else:
|
|
if level == Level.RESET:
|
|
_defaultLogLevel = Level.NOTICE
|
|
_moduleLogLevel = {}
|
|
else:
|
|
_defaultLogLevel = level
|
|
|
|
|
|
def getLevel(module=None):
|
|
"""(module = None) - return the global (None) or module specific log level."""
|
|
if module:
|
|
return _moduleLogLevel.get(module, _defaultLogLevel)
|
|
return _defaultLogLevel
|
|
|
|
|
|
def thisModule():
|
|
"""returns the module id of the caller, can be used for setLevel, getLevel and trackModule."""
|
|
return _caller()[0]
|
|
|
|
|
|
def _caller():
|
|
"""internal function to determine the calling module."""
|
|
filename, line, func, text = traceback.extract_stack(limit=3)[0]
|
|
return os.path.splitext(os.path.basename(filename))[0], line, func
|
|
|
|
|
|
def _log(level, module_line_func, msg):
|
|
"""internal function to do the logging"""
|
|
module, line, func = module_line_func
|
|
|
|
if getLevel(module) >= level:
|
|
message = "%s.%s: %s" % (module, Level.toString(level), msg)
|
|
if _useConsole:
|
|
message += "\n"
|
|
if level == Level.NOTICE:
|
|
FreeCAD.Console.PrintLog(message)
|
|
elif level == Level.WARNING:
|
|
FreeCAD.Console.PrintWarning(message)
|
|
elif level == Level.ERROR:
|
|
FreeCAD.Console.PrintError(message)
|
|
else:
|
|
FreeCAD.Console.PrintMessage(message)
|
|
else:
|
|
print(message)
|
|
return message
|
|
return None
|
|
|
|
|
|
def debug(msg):
|
|
"""(message)"""
|
|
caller_info = _caller()
|
|
_, line, _ = caller_info
|
|
msg = "({}) - {}".format(line, msg)
|
|
return _log(Level.DEBUG, caller_info, msg)
|
|
|
|
|
|
def info(msg):
|
|
"""(message)"""
|
|
return _log(Level.INFO, _caller(), msg)
|
|
|
|
|
|
def notice(msg):
|
|
"""(message)"""
|
|
return _log(Level.NOTICE, _caller(), msg)
|
|
|
|
|
|
def warning(msg):
|
|
"""(message)"""
|
|
return _log(Level.WARNING, _caller(), msg)
|
|
|
|
|
|
def error(msg):
|
|
"""(message)"""
|
|
return _log(Level.ERROR, _caller(), msg)
|
|
|
|
|
|
def trackAllModules(boolean):
|
|
"""(boolean) - if True all modules will be tracked, otherwise tracking is up to the module setting."""
|
|
global _trackAll
|
|
_trackAll = boolean
|
|
|
|
|
|
def untrackAllModules():
|
|
"""In addition to stop tracking all modules it also clears the tracking flag for all individual modules."""
|
|
global _trackAll
|
|
global _trackModule
|
|
_trackAll = False
|
|
_trackModule = {}
|
|
|
|
|
|
def trackModule(module=None):
|
|
"""(module = None) - start tracking given module, current module if not set."""
|
|
global _trackModule
|
|
if module:
|
|
_trackModule[module] = True
|
|
else:
|
|
mod, line, func = _caller()
|
|
_trackModule[mod] = True
|
|
|
|
|
|
def untrackModule(module=None):
|
|
"""(module = None) - stop tracking given module, current module if not set."""
|
|
global _trackModule
|
|
if module and _trackModule.get(module, None):
|
|
del _trackModule[module]
|
|
elif not module:
|
|
mod, line, func = _caller()
|
|
if _trackModule.get(mod, None):
|
|
del _trackModule[mod]
|
|
|
|
|
|
def track(*args):
|
|
"""(....) - call with arguments of current function you want logged if tracking is enabled."""
|
|
module, line, func = _caller()
|
|
if _trackAll or _trackModule.get(module, None):
|
|
message = "%s(%d).%s(%s)" % (
|
|
module,
|
|
line,
|
|
func,
|
|
", ".join([str(arg) for arg in args]),
|
|
)
|
|
if _useConsole:
|
|
FreeCAD.Console.PrintMessage(message + "\n")
|
|
else:
|
|
print(message)
|
|
return message
|
|
return None
|