From cc16b178bb70aa349772017f4eed7b9ef4b1d9f3 Mon Sep 17 00:00:00 2001 From: "Zheng, Lei" Date: Mon, 30 Oct 2017 03:52:54 +0800 Subject: [PATCH] FCADLogger: add hierarchy log level support Each module now has their own logger, and can be controlled separately --- FCADLogger.py | 49 ++++++++++++++++++++++++++++++++++++++++++++++--- constraint.py | 29 ++++++++++++----------------- gui.py | 10 +++++++--- proxy.py | 2 +- solver.py | 2 +- sys_slvs.py | 2 +- sys_sympy.py | 2 +- system.py | 2 +- utils.py | 7 ++++++- 9 files changed, 76 insertions(+), 29 deletions(-) diff --git a/FCADLogger.py b/FCADLogger.py index 8058279..8a5be9e 100644 --- a/FCADLogger.py +++ b/FCADLogger.py @@ -14,14 +14,19 @@ class FCADLogger: FreeCAD.Console.PrintLog, FreeCAD.Console.PrintLog ] self.laststamp = datetime.now() - for key in ('printTag','noUpdateUI','timing','lineno'): - setattr(self,key,kargs.get(key,True)) + for key,default in (('printTag',True),('noUpdateUI',True), + ('timing',True),('lineno',True),('parent',None)): + setattr(self,key,kargs.get(key,default)) def _isEnabledFor(self,level): + if self.parent and not self.parent._isEnabledFor(level): + return False return FreeCAD.getLogLevel(self.tag) >= level def isEnabledFor(self,level): - self._isEnabledOf(self.levels[level]) + if not isinstance(level,int): + level = self.levels[level] + return self._isEnabledFor(level) def error(self,msg,frame=0): self.log(0,msg,frame+1) @@ -68,3 +73,41 @@ class FCADLogger: FreeCADGui.updateGui() except Exception: pass + + def _catch(self,level,msg,func,args=None,kargs=None): + try: + if not args: + args = [] + if not kargs: + kargs = {} + return func(*args,**kargs) + except Exception: + if self._isEnabledFor(level): + import traceback + self.log(level,msg+'\n'+traceback.format_exc(),frame=2) + + def catch(self,msg,func,*args,**kargs): + return self._catch(0,msg,func,args,kargs) + + def catchWarn(self,msg,func,*args,**kargs): + return self._catch(1,msg,func,args,kargs) + + def catchInfo(self,msg,func,*args,**kargs): + return self._catch(2,msg,func,args,kargs) + + def catchDebug(self,msg,func,*args,**kargs): + return self._catch(3,msg,func,args,kargs) + + def catchTrace(self,msg,func,*args,**kargs): + return self._catch(4,msg,func,args,kargs) + + def report(self,msg,func,*args,**kargs): + try: + return func(*args,**kargs) + except Exception as e: + import traceback + self.error(msg+'\n'+traceback.format_exc(),frame=1) + + import PySide + PySide.QtGui.QMessageBox.critical( + FreeCADGui.getMainWindow(),'Assembly',e.message) diff --git a/constraint.py b/constraint.py index d5553ad..6cd2bb3 100644 --- a/constraint.py +++ b/constraint.py @@ -1,9 +1,9 @@ from future.utils import with_metaclass from collections import namedtuple import FreeCAD, FreeCADGui +import asm3 import asm3.utils as utils -from asm3.gui import AsmCmdManager -from asm3.utils import logger, objName +from asm3.utils import objName,cstrlogger as logger, guilogger from asm3.proxy import ProxyType, PropertyInfo, propGet, propGetValue import os @@ -153,6 +153,7 @@ class ConstraintCommand: def __init__(self,tp): self.tp = tp self._id = 100 + tp._id + self._active = False def workbenchActivated(self): pass @@ -170,25 +171,20 @@ class ConstraintCommand: return self.tp.GetResources() def Activated(self): - from asm3.assembly import AsmConstraint - AsmConstraint.make(self.tp._id) + guilogger.report('constraint "{}" command exception'.format( + self.tp.getName()), asm3.assembly.AsmConstraint.make,self.tp._id) def IsActive(self): - return FreeCADGui.ActiveDocument and self.tp._active + return FreeCADGui.ActiveDocument and self._active def checkActive(self): from asm3.assembly import AsmConstraint - try: - AsmConstraint.getSelection(self.tp._id) - except Exception as e: - logger.trace('selection "{}" exception: {}'.format( - self.tp.getName(),e.message),frame=1) - self.tp._active = False - else: - self.tp._active = True + if guilogger.catchTrace('selection "{}" exception'.format( + self.tp.getName()), AsmConstraint.getSelection, self.tp._id): + self._active = True def onClearSelection(self): - self.tp._active = False + self._active = False class Constraint(ProxyType): 'constraint meta class' @@ -200,8 +196,8 @@ class Constraint(ProxyType): @classmethod def register(mcs,cls): super(Constraint,mcs).register(cls) - if cls._menuItem: - AsmCmdManager.register(ConstraintCommand(cls)) + if cls._id>=0 and cls._menuItem: + asm3.gui.AsmCmdManager.register(ConstraintCommand(cls)) @classmethod def attach(mcs,obj,checkType=True): @@ -271,7 +267,6 @@ class Base(with_metaclass(Constraint,object)): _iconName = 'Assembly_ConstraintGeneral.svg' _menuText = 'Create "{}" constraint' - _active = False _menuItem = False def __init__(self,_obj): diff --git a/gui.py b/gui.py index 8d7e158..041f3bf 100644 --- a/gui.py +++ b/gui.py @@ -2,8 +2,9 @@ from future.utils import with_metaclass from collections import OrderedDict import FreeCAD, FreeCADGui import asm3 -from asm3.utils import logger,objName,addIconToFCAD +from asm3.utils import objName,addIconToFCAD,guilogger as logger from asm3.proxy import ProxyType +from asm3.FCADLogger import FCADLogger class SelectionObserver: def __init__(self, cmds): @@ -28,12 +29,14 @@ class SelectionObserver: cmd.onClearSelection() def attach(self): + logger.trace('attach selection aboserver {}'.format(self._attached)) if not self._attached: FreeCADGui.Selection.addObserver(self) self._attached = True self.onChanged() def detach(self): + logger.trace('detach selection aboserver {}'.format(self._attached)) if self._attached: FreeCADGui.Selection.removeObserver(self) self._attached = False @@ -128,8 +131,9 @@ class AsmCmdSolve(AsmCmdBase): @classmethod def Activated(cls): - import asm3.solver as solver - solver.solve() + logger.report('command "{}" exception'.format(cls.getName()), + asm3.solver.solve) + class AsmCmdMove(AsmCmdBase): _id = 2 diff --git a/proxy.py b/proxy.py index fccb719..6eefa37 100644 --- a/proxy.py +++ b/proxy.py @@ -1,6 +1,6 @@ import past.builtins as pb from collections import namedtuple -from asm3.utils import logger, objName +from asm3.utils import proxylogger as logger, objName def propGet(self,obj): return getattr(obj,self.Name) diff --git a/solver.py b/solver.py index 2c76895..960db6b 100644 --- a/solver.py +++ b/solver.py @@ -2,7 +2,7 @@ import random from collections import namedtuple import FreeCAD, FreeCADGui import asm3.assembly as asm -from asm3.utils import logger, objName, isSamePlacement +from asm3.utils import syslogger as logger, objName, isSamePlacement from asm3.constraint import Constraint, cstrName from asm3.system import System diff --git a/sys_slvs.py b/sys_slvs.py index 5e5ff56..7de0579 100644 --- a/sys_slvs.py +++ b/sys_slvs.py @@ -1,6 +1,6 @@ from future.utils import with_metaclass from asm3.system import System, SystemBase, SystemExtension -from asm3.utils import logger, objName +from asm3.utils import syslogger as logger, objName import asm3.py_slvs.slvs as slvs class SystemSlvs(with_metaclass(System,SystemBase)): diff --git a/sys_sympy.py b/sys_sympy.py index 7145866..4871dec 100644 --- a/sys_sympy.py +++ b/sys_sympy.py @@ -3,7 +3,7 @@ from future.utils import with_metaclass, iteritems import pprint from asm3.proxy import ProxyType, PropertyInfo from asm3.system import System, SystemBase, SystemExtension -from asm3.utils import logger, objName +from asm3.utils import syslogger as logger, objName import sympy as sp import sympy.vector as spv import scipy.optimize as sopt diff --git a/system.py b/system.py index 748d528..886c9e0 100644 --- a/system.py +++ b/system.py @@ -1,7 +1,7 @@ import os from future.utils import with_metaclass import asm3.utils as utils -from asm3.utils import logger, objName +from asm3.utils import syslogger as logger, objName from asm3.proxy import ProxyType, PropertyInfo class System(ProxyType): diff --git a/utils.py b/utils.py index accd7e0..7ca0e18 100644 --- a/utils.py +++ b/utils.py @@ -8,7 +8,12 @@ assembly2 import FreeCAD, FreeCADGui, Part import numpy as np from asm3.FCADLogger import FCADLogger -logger = FCADLogger('asm3') +rootlogger = FCADLogger('asm3') +logger = FCADLogger('asm3.main',parent=rootlogger) +guilogger = FCADLogger('asm3.gui',parent=rootlogger) +cstrlogger = FCADLogger('asm3.cstr',parent=rootlogger) +syslogger = FCADLogger('asm3.sys',parent=rootlogger) +proxylogger = FCADLogger('asm3.proxy',parent=rootlogger) import sys, os modulePath = os.path.dirname(os.path.realpath(__file__))