Example #1
0
def make_logger(log_level=None, logger=Logger, observer=log_publisher):
    """
    Make a new logger (of the type set by the kwarg logger) that publishes to
    the observer set in the observer kwarg. If no explicit log_level is given,
    it uses the current global log level.
    """
    # Get the caller's frame
    cf = currentframe(1)

    if "self" in cf.f_locals:
        # We're probably in a class init or method
        namespace = qual(cf.f_locals["self"].__class__)

        logger = CrossbarLogger(log_level,
                                namespace=namespace,
                                logger=logger,
                                observer=observer)
    else:
        namespace = cf.f_globals["__name__"]

        if cf.f_code.co_name != "<module>":
            # If it's not the module, and not in a class instance, add the code
            # object's name.
            namespace = namespace + "." + cf.f_code.co_name

        logger = CrossbarLogger(log_level,
                                namespace=namespace,
                                logger=logger,
                                observer=observer)

    # Set up a weak ref, so that all loggers can be updated later
    _loggers[logger] = True
    return logger
Example #2
0
    def _namespaceFromCallingContext():
        """
        Derive a namespace from the module containing the caller's caller.

        @return: the fully qualified python name of a module.
        @rtype: L{str} (native string)
        """
        return currentframe(2).f_globals["__name__"]
Example #3
0
def nextLine():
    """
    Retrive the file name and line number immediately after where this function
    is called.

    @return: the file name and line number
    @rtype: 2-L{tuple} of L{str}, L{int}
    """
    caller = currentframe(1)
    return (getsourcefile(sys.modules[caller.f_globals['__name__']]),
            caller.f_lineno + 1)
Example #4
0
def nextLine():
    """
    Retrive the file name and line number immediately after where this function
    is called.

    @return: the file name and line number
    @rtype: 2-L{tuple} of L{str}, L{int}
    """
    caller = currentframe(1)
    return (getsourcefile(sys.modules[caller.f_globals['__name__']]),
            caller.f_lineno + 1)
Example #5
0
    def _namespaceFromCallingContext():
        """
        Derive a namespace from the module containing the caller's caller.

        @return: the fully qualified python name of a module.
        @rtype: L{str} (native string)
        """
        try:
            return currentframe(2).f_globals["__name__"]
        except KeyError:
            return "<unknown>"
Example #6
0
def nextLine() -> Tuple[Optional[str], int]:
    """
    Retrive the file name and line number immediately after where this function
    is called.

    @return: the file name and line number
    """
    caller = currentframe(1)
    return (
        getsourcefile(sys.modules[caller.f_globals["__name__"]]),
        caller.f_lineno + 1,
    )
Example #7
0
def getDataDirectory(moduleName=None):
    """
    Get a data directory for the caller function, or C{moduleName} if given.

    @param moduleName: The module name if you don't wish to have the caller's
        module.
    @type moduleName: L{str}

    @returns: A directory for putting data in.
    @rtype: L{str}
    """
    if not moduleName:
        caller = currentframe(1)
        moduleName = inspect.getmodule(caller).__name__

    return appdirs.user_data_dir(moduleName)
def getDataDirectory(moduleName: str = "") -> str:
    """
    Get a data directory for the caller function, or C{moduleName} if given.

    @param moduleName: The module name if you don't wish to have the caller's
        module.

    @returns: A directory for putting data in.
    """
    if not moduleName:
        caller = currentframe(1)
        module = inspect.getmodule(caller)
        assert module is not None
        moduleName = module.__name__

    return cast(str, appdirs.user_data_dir(moduleName))
Example #9
0
def getDataDirectory(moduleName=None):
    """
    Get a data directory for the caller function, or C{moduleName} if given.

    @param moduleName: The module name if you don't wish to have the caller's
        module.
    @type moduleName: L{str}

    @returns: A directory for putting data in.
    @rtype: L{str}
    """
    if not moduleName:
        caller = currentframe(1)
        moduleName = inspect.getmodule(caller).__name__

    return appdirs.user_data_dir(moduleName)
Example #10
0
    def _findCaller(self,
                    stackInfo: bool = False,
                    stackLevel: int = 1) -> Tuple[str, int, str, None]:
        """
        Based on the stack depth passed to this L{STDLibLogObserver}, identify
        the calling function.

        @param stackInfo: Whether or not to construct stack information.
            (Currently ignored.)
        @param stackLevel: The number of stack frames to skip when determining
            the caller (currently ignored; use stackDepth on the instance).

        @return: Depending on Python version, either a 3-tuple of (filename,
            lineno, name) or a 4-tuple of that plus stack information.
        """
        f = currentframe(self.stackDepth)
        co = f.f_code
        extra = (None, )
        return (co.co_filename, f.f_lineno, co.co_name) + extra
Example #11
0
    def _from_stack(cls, function=None):
        """
        Should only be called by py:`LockableDatabase.transaction`.

        Find the caller of and construct an exception referencing it. This will
        skip over the wrapper from :py:`with_cursor`.

        This must be called on a subclass that defines `.message`.
        """
        # There are 2 stack frames between this function
        # 0. _LockableDatabaseTransactionError.from_stack
        # 1. LockableDatabase.transaction
        # 2. contextlib.contextmanger's __enter__
        # 3. Our caller (potentially with_cursor)
        frame = currentframe(3)
        if frame.f_code == with_cursor._wrapped_code:
            frame = frame.f_back
        caller = frame.f_code.co_name
        return cls(caller=caller, function=function)
Example #12
0
    def _findCaller(self, stackInfo=False):
        """
        Based on the stack depth passed to this L{STDLibLogObserver}, identify
        the calling function.

        @param stackInfo: Whether or not to construct stack information.
            (Currently ignored.)
        @type stackInfo: L{bool}

        @return: Depending on Python version, either a 3-tuple of (filename,
            lineno, name) or a 4-tuple of that plus stack information.
        @rtype: L{tuple}
        """
        f = currentframe(self.stackDepth)
        co = f.f_code
        if _PY3:
            extra = (None, )
        else:
            extra = ()
        return (co.co_filename, f.f_lineno, co.co_name) + extra
Example #13
0
    def _findCaller(self, stackInfo=False):
        """
        Based on the stack depth passed to this L{STDLibLogObserver}, identify
        the calling function.

        @param stackInfo: Whether or not to construct stack information.
            (Currently ignored.)
        @type stackInfo: L{bool}

        @return: Depending on Python version, either a 3-tuple of (filename,
            lineno, name) or a 4-tuple of that plus stack information.
        @rtype: L{tuple}
        """
        f = currentframe(self.stackDepth)
        co = f.f_code
        if _PY3:
            extra = (None,)
        else:
            extra = ()
        return (co.co_filename, f.f_lineno, co.co_name) + extra
Example #14
0
    def beginLoggingTo(
        self, observers, discardBuffer=False, redirectStandardIO=True
    ):
        """
        Begin logging to the given set of observers.  This will:

            1. Add all the observers given in C{observers} to the
               L{LogPublisher} associated with this L{LogBeginner}.

            2. Optionally re-direct standard output and standard error streams
               to the logging system.

            3. Re-play any messages that were previously logged to that
               publisher to the new observers, if C{discardBuffer} is not set.

            4. Stop logging critical errors from the L{LogPublisher} as strings
               to the C{errorStream} associated with this L{LogBeginner}, and
               allow them to be logged normally.

            5. Re-direct warnings from the L{warnings} module associated with
               this L{LogBeginner} to log messages.

        @note: Since a L{LogBeginner} is designed to encapsulate the transition
            between process-startup and log-system-configuration, this method
            is intended to be invoked I{once}.

        @param observers: The observers to register.
        @type observers: iterable of L{ILogObserver}s

        @param discardBuffer: Whether to discard the buffer and not re-play it
            to the added observers.  (This argument is provided mainly for
            compatibility with legacy concerns.)
        @type discardBuffer: L{bool}

        @param redirectStandardIO: If true, redirect standard output and
            standard error to the observers.
        @type redirectStandardIO: L{bool}
        """
        caller = currentframe(1)
        filename, lineno = caller.f_code.co_filename, caller.f_lineno

        for observer in observers:
            self._publisher.addObserver(observer)

        if self._temporaryObserver is not None:
            self._publisher.removeObserver(self._temporaryObserver)
            if not discardBuffer:
                self._initialBuffer.replayTo(self._publisher)
            self._temporaryObserver = None
            self._warningsModule.showwarning = self.showwarning
        else:
            previousFile, previousLine = self._previousBegin
            self._log.warn(
                MORE_THAN_ONCE_WARNING,
                fileNow=filename, lineNow=lineno,
                fileThen=previousFile, lineThen=previousLine,
            )

        self._previousBegin = filename, lineno
        if redirectStandardIO:
            streams = [("stdout", LogLevel.info), ("stderr", LogLevel.error)]
        else:
            streams = []

        for (stream, level) in streams:
            oldStream = getattr(self._stdio, stream)
            loggingFile = LoggingFile(
                logger=Logger(namespace=stream, observer=self._publisher),
                level=level,
                encoding=getattr(oldStream, "encoding", None),
            )
            setattr(self._stdio, stream, loggingFile)
Example #15
0
File: _global.py Project: DT021/wau
    def beginLoggingTo(self,
                       observers,
                       discardBuffer=False,
                       redirectStandardIO=True):
        """
        Begin logging to the given set of observers.  This will:

            1. Add all the observers given in C{observers} to the
               L{LogPublisher} associated with this L{LogBeginner}.

            2. Optionally re-direct standard output and standard error streams
               to the logging system.

            3. Re-play any messages that were previously logged to that
               publisher to the new observers, if C{discardBuffer} is not set.

            4. Stop logging critical errors from the L{LogPublisher} as strings
               to the C{errorStream} associated with this L{LogBeginner}, and
               allow them to be logged normally.

            5. Re-direct warnings from the L{warnings} module associated with
               this L{LogBeginner} to log messages.

        @note: Since a L{LogBeginner} is designed to encapsulate the transition
            between process-startup and log-system-configuration, this method
            is intended to be invoked I{once}.

        @param observers: The observers to register.
        @type observers: iterable of L{ILogObserver}s

        @param discardBuffer: Whether to discard the buffer and not re-play it
            to the added observers.  (This argument is provided mainly for
            compatibility with legacy concerns.)
        @type discardBuffer: L{bool}

        @param redirectStandardIO: If true, redirect standard output and
            standard error to the observers.
        @type redirectStandardIO: L{bool}
        """
        caller = currentframe(1)
        filename, lineno = caller.f_code.co_filename, caller.f_lineno

        for observer in observers:
            self._publisher.addObserver(observer)

        if self._temporaryObserver is not None:
            self._publisher.removeObserver(self._temporaryObserver)
            if not discardBuffer:
                self._initialBuffer.replayTo(self._publisher)
            self._temporaryObserver = None
            self._warningsModule.showwarning = self.showwarning
        else:
            previousFile, previousLine = self._previousBegin
            self._log.warn(
                MORE_THAN_ONCE_WARNING,
                fileNow=filename,
                lineNow=lineno,
                fileThen=previousFile,
                lineThen=previousLine,
            )

        self._previousBegin = filename, lineno
        if redirectStandardIO:
            streams = [("stdout", LogLevel.info), ("stderr", LogLevel.error)]
        else:
            streams = []

        for (stream, level) in streams:
            oldStream = getattr(self._stdio, stream)
            loggingFile = LoggingFile(
                logger=Logger(namespace=stream, observer=self._publisher),
                level=level,
                encoding=getattr(oldStream, "encoding", None),
            )
            setattr(self._stdio, stream, loggingFile)