Пример #1
0
 def filter(self, record: logging.LogRecord) -> bool:
     if isinstance(record.args, collections.abc.Mapping):
         record.args = {
             self.redact(k): self.redact(v)
             for k, v in record.args.items()  # type: ignore
         }
     else:
         if record.args is not None:
             record.args = tuple(self.redact(a) for a in record.args)
     return True
 def _color_record_args(self, record: LogRecord) -> LogRecord:
     if isinstance(record.args, (tuple, list)):
         record.args = tuple(self._color_arg(arg) for arg in record.args)
     elif isinstance(record.args, dict):
         # Case of logging.debug("a %(a)d b %(b)s", {'a':1, 'b':2})
         record.args = {
             key: self._color_arg(value) for key, value in record.args.items()
         }
     elif isinstance(record.args, str):
         record.args = self._color_arg(record.args)
     return record
 def _format_args(self, record: logging.LogRecord) -> None:
     if isinstance(record.args, Mapping):
         # logger.log(severity, "msg %(foo)s", foo=303)
         record.args = {
             k: self._format_arg(v)
             for k, v in record.args.items()
         }
     else:
         if not isinstance(record.args, tuple):
             # logger.log(severity, "msg %s", foo)
             record.args = (record.args, )
         # logger.log(severity, "msg %s", ('foo',))
         record.args = tuple(self._format_arg(arg) for arg in record.args)
Пример #4
0
 def _color_record_args(self, record: LogRecord) -> LogRecord:
     if isinstance(record.args, (tuple, list)):
         record.args = tuple(self._color_arg(arg) for arg in record.args)
     elif isinstance(record.args, dict):
         if self._count_number_of_arguments_in_message(record) > 1:
             # Case of logging.debug("a %(a)d b %(b)s", {'a':1, 'b':2})
             record.args = {
                 key: self._color_arg(value) for key, value in record.args.items()
             }
         else:
             # Case of single dict passed to formatted string
             record.args = self._color_arg(record.args)   # type: ignore
     elif isinstance(record.args, str):
         record.args = self._color_arg(record.args)
     return record
Пример #5
0
 def _format_args(self, record: logging.LogRecord) -> None:
     if isinstance(record.args, Mapping):
         # logger.log(severity, "msg %(foo)s", foo=303)
         record.args = {
             k: self._format_arg(v)
             for k, v in record.args.items()
         }
     else:
         if not isinstance(record.args, tuple):
             # logger.log(severity, "msg %s", foo)
             # mypy thinks this is unreachable as record is
             # always Tuple
             record.args = (record.args, )  # type: ignore
         # logger.log(severity, "msg %s", ('foo',))
         record.args = tuple(self._format_arg(arg) for arg in record.args)
Пример #6
0
    def filter(self, record: LogRecord) -> bool:
        if record.args == ():
            record.args = {}
        elif isinstance(record.args, dict):
            record.args.update({"sensor": self.sensorID})

        return True
Пример #7
0
    def format(self, record: logging.LogRecord) -> str:
        """Custom formating for the log message.

        If the record contains an exception, then add that to the 'message'. Heroku
        splits the message according to newline and thus the color format will
        disappear, so add the color format after every newline as well.
        """
        custom_fmt = self.LOG_LEVEL_FORMAT.get(record.levelname,
                                               self.default_fmt)
        # Inject custom formating to the base class which `self.formatMessage` calls.
        self._style._fmt = custom_fmt
        if record.args and isinstance(record.args, MutableMapping):
            record.args = format_args(record.args, record.levelname)
        msg = record.getMessage()
        if record.exc_info:
            if not record.exc_text:
                record.exc_text = self.formatException(record.exc_info)
        if record.exc_text:
            if msg[-1:] != "\n":
                msg += "\n"
            msg += record.exc_text
            c = getattr(AnsiColor, record.levelname)
            msg = msg.replace("\n", f"\n{c}")
        if record.stack_info:
            if msg[-1:] != "\n":
                msg += "\n"
            msg += self.formatStack(record.stack_info)
        record.message = msg
        return self.formatMessage(record)
Пример #8
0
 def filter(self, record: logging.LogRecord) -> bool:
     """Pass the record's message to the monitor, add colors to the message."""
     message = record.getMessage()
     self._monitor.add_event_sync(message)
     if self._color:
         record.msg = colors.color(message, fg=self._color)
     record.args = ()
     return True
Пример #9
0
    def format(self, record: logging.LogRecord) -> str:
        """
        Extract ``structlog``'s `event_dict` from ``record.msg`` and format it.

        *record* has been patched by `wrap_for_formatter` first though, so the
         type isn't quite right.
        """
        # Make a shallow copy of the record to let other handlers/formatters
        # process the original one
        record = logging.makeLogRecord(record.__dict__)

        logger = getattr(record, "_logger", _SENTINEL)
        meth_name = getattr(record, "_name", _SENTINEL)

        if logger is not _SENTINEL and meth_name is not _SENTINEL:
            # Both attached by wrap_for_formatter
            if self.logger is not None:
                logger = self.logger
            meth_name = record._name  # type: ignore

            # We need to copy because it's possible that the same record gets
            # processed by multiple logging formatters.  LogRecord.getMessage
            # would transform our dict into a str.
            ed = record.msg.copy()  # type: ignore
        else:
            logger = self.logger
            meth_name = record.levelname.lower()
            ed = {"event": record.getMessage(), "_record": record}

            if self.pass_foreign_args:
                ed["positional_args"] = record.args

            record.args = ()

            # Add stack-related attributes to event_dict and unset them
            # on the record copy so that the base implementation wouldn't
            # append stacktraces to the output.
            if record.exc_info:
                ed["exc_info"] = record.exc_info
            if record.stack_info:
                ed["stack_info"] = record.stack_info

            if not self.keep_exc_info:
                record.exc_text = None
                record.exc_info = None
            if not self.keep_stack_info:
                record.stack_info = None

            # Non-structlog allows to run through a chain to prepare it for the
            # final processor (e.g. adding timestamps and log levels).
            for proc in self.foreign_pre_chain or ():
                ed = proc(logger, meth_name, ed)

            del ed["_record"]

        record.msg = self.processor(logger, meth_name, ed)  # type: ignore

        return super().format(record)
Пример #10
0
    def filter(self, record: LogRecord) -> bool:
        if isinstance(record.args, tuple):
            record.args = {}

        clientInfo = self.server.tcp.transport.client
        record.args.update({
            "src_ip": clientInfo[0],
            "src_port": clientInfo[1],
            "session": self.sessionId
        })

        return True
Пример #11
0
    def _format_record(self, record: logging.LogRecord=None) -> logging.LogRecord:
        """
        Formatted the LogRecord
        :param record: LogRecord with the message info
        :return: LogRecord with formatted message
        """
        # ensure that exc_info and args
        # have been stringified. Removes any chance of
        # unpickleable things inside and possibly reduces
        # message size sent over the pipe.
        if record.args:
            record.msg = record.msg % record.args
            record.args = None
        if record.exc_info:
            self.format(record)
            record.exc_info = None

        return record
Пример #12
0
    def _format_record(self,
                       record: logging.LogRecord = None) -> logging.LogRecord:
        """
        Formatted the LogRecord
        :param record: LogRecord with the message info
        :return: LogRecord with formatted message
        """
        # ensure that exc_info and args
        # have been stringified. Removes any chance of
        # unpickleable things inside and possibly reduces
        # message size sent over the pipe.
        if record.args:
            record.msg = record.msg % record.args
            record.args = None
        if record.exc_info:
            self.format(record)
            record.exc_info = None

        return record
Пример #13
0
 def filter(self, record: logging.LogRecord) -> int:
     if hasattr(record, 'msg'):
         for secret in self._secrets:
             if secret:
                 record.msg = record.msg.replace(str(secret), "***")
     if isinstance(record.args, dict):
         for key in record.args:
             for secret in self._secrets:
                 if secret:
                     record.args[key] = record.args[key].replace(
                         str(secret), "***")
     else:
         nargs = []
         for i in range(len(record.args)):
             for secret in self._secrets:
                 if secret:
                     nargs.append(record.args[i].replace(
                         str(secret), "***"))
         record.args = tuple(nargs)
     return True
Пример #14
0
    def _convert_record(self, record: logging.LogRecord) -> logging.LogRecord:
        # we store the originating DagsterEvent in the DAGSTER_META_KEY field, if applicable
        dagster_meta = getattr(record, DAGSTER_META_KEY, None)

        # generate some properties for this specific record
        dagster_message_props = DagsterMessageProps(
            orig_message=record.getMessage(), dagster_event=dagster_meta
        )

        # set the dagster meta info for the record
        setattr(
            record,
            DAGSTER_META_KEY,
            get_dagster_meta_dict(self._logging_metadata, dagster_message_props),
        )

        # update the message to be formatted like other dagster logs
        record.msg = construct_log_string(self._logging_metadata, dagster_message_props)
        record.args = ()

        return record
Пример #15
0
    def rewrite_record(record: logging.LogRecord):
        if not BraceFormatStyleFormatter.is_brace_format_style(record):
            return

        msg = record.msg
        msg = msg.replace("{", "_{{")
        msg = msg.replace("}", "_}}")
        placeholder_count = 0
        # add ANSI escape code for next alternating color before each formatting parameter
        # and reset color after it.
        while True:
            if "_{{" not in msg:
                break
            color_index = placeholder_count % len(ColorizedArgsFormatter.arg_colors)
            color = ColorizedArgsFormatter.arg_colors[color_index]
            msg = msg.replace("_{{", color + "{", 1)
            msg = msg.replace("_}}", "}" + ColorCodes.reset, 1)
            placeholder_count += 1

        record.msg = msg.format(*record.args)
        record.args = []
Пример #16
0
 def _format_line(record: logging.LogRecord, msg: str) -> str:
     record = copy(record)
     record.msg = msg
     record.args = ()
     return _super_format(record)
Пример #17
0
    def format(self, record: logging.LogRecord) -> str:
        """ Format message Object (via attributes of LogRecord) of unknown type into printable and easily readable string

        The *Parameters* are fed in through `record`

        Parameters
        ----------
        msg
            actual output, could be object, string
        heading
            title is gerated from this

        Notes
        -----
        `record.getMessage()` will ALWAYS return a `str()`
                for the actual object the user provided use `record.msg`

        See Also
        --------
        https://docs.python.org/3/library/logging.html#logging.LogRecord
        https://docs.python.org/3/library/logging.html#logrecord-attributes

        """
        if record.args is None: record.args = []
        level_print = str()
        prepend = str()
        prependtime = str()
        output = record.msg if hasattr(record, "msg") else str()
        location = str()
        highlight_color = str()
        heading = record.args[
            'heading'] if 'heading' in record.args and record.args[
                'heading'] is not False else False
        title = heading if heading is not False and type(
            heading) is str else str()
        # if there are newlines in the output, make it a block.
        try:
            if repr(output).count("\n") > 1:
                heading = True
        except Exception as e:
            logging_error(
                f"Failure in {self.__class__.__name__} when requesting repr of {output.__class__.__name__} with exception:\n\t{e}"
            )
        # typically closing is done in the same log message as heading
        # but this is disabled when in context
        closing = heading
        context_marker = str()
        context = record.args[
            'context'] if 'context' in record.args and record.args[
                'context'] in (LogContextStatus.OPENING,
                               LogContextStatus.CURRENT,
                               LogContextStatus.CLOSING) else False
        clear = self.clear
        eol = self.eol
        emphasis = record.args[
            "emphasis"] if 'emphasis' in record.args else False
        relatime = record.args[
            "relatime"] if 'relatime' in record.args else False
        stack_trace = record.args[
            'stack_trace'] if "stack_trace" in record.args and type(
                record.args['stack_trace']) is list else False
        flag_location = record.args[
            "location"] if 'location' in record.args else False
        table = record.args["table"] if 'table' in record.args else False

        # flag_location = True   # TODO: KILL
        # try:
        if isinstance(output, str):
            pass  # not a table; this is a string, no further processing
        elif not isinstance(output, type) and hasattr(
                output, "to_string") and callable(output.to_string):
            # mostly useful for pandas.DataFrame
            from lib.shared.util import FormatDataFrame
            with FormatDataFrame(max_colwidth=0):
                output = output.to_string()
        # elif table or isinstance(output, (Mapping, list)):
        elif table:
            # if table and title, set title to heading
            iterate_source = output
            output = str()
            title = title if title else str(type(iterate_source))
            if isinstance(iterate_source, Mapping):
                iterate_source = iterate_source.items()
            elif isinstance(iterate_source, list):
                iterate_source = {k: v
                                  for k, v in enumerate(iterate_source)
                                  }.items()
            try:
                iterate_source = iter(iterate_source)
                # determine the width of what is added as a table row.
                # Don't exceed console width
                max_len = 0
                for d in iterate_source:
                    _row = self.make_row(*d)
                    max_len = len(_row) if len(_row) > max_len else max_len
                    # output += f" Len({len(self.make_row(*d))}) "
                    output += _row
                # print(f"title={title}\nheading={heading}\nmaxlen({max_len})+lentitle({len(title)})+lenheading({len(heading)})")
                # if ( max_len + len(title) + len(record.args['title']) ) > self.console_width:
                #     output = "\n" + output
            except TypeError:
                output += repr(output)
                raise TypeError(
                    "Best handled elsewhere: you requested a table, but this isn't iterable"
                )
        else:
            # when the object is not a string
            try:
                output = pprint.pformat(output,
                                        width=self.output_width,
                                        indent=4)
            except Exception as e:
                raise LogFormatException(
                    f"This is neither a table, nor a string.\nError encountered while using fallback pformat method:\n{e}"
                )

        if record.levelno == logging.WARNING:  # add levelname
            level_print = f"{record.levelname} "
        if record.levelno == logging.CRITICAL:  # add levelname
            level_print = f"{record.levelname} "
            highlight_color = self.COLOR_HIGHLIGHT_CRITICAL if self.color else ""

        if logging.getLogger(__name__).getEffectiveLevel() <= Level.DEBUG:
            # NOTE: THIS IS VERY LENGTHY LOGGING
            print(f"args={record.args}")
            print(f"exc_info={record.exc_info}")
            print(f"filename={record.filename}")
            print(f"funcName={record.funcName}")
            print(f"lineno={record.lineno}")
            print(f"pathname={record.pathname}")
            print(f"stack_info={record.stack_info}")
            print(f"flag_location={flag_location}")
            print(f"---- exc_info[3] {type(record.exc_info[2])}--->")
            print(traceback.extract_tb(record.exc_info[2]))
        # https://docs.python.org/3/library/traceback.html#module-traceback
        if record.levelno == logging.CRITICAL and type(
                record.exc_info) is tuple and type(
                    record.exc_info[2]) is not None:
            trace = traceback.extract_tb(record.exc_info[2])
            last = trace[len(trace) - 1]
            if logging.getLogger(__name__).getEffectiveLevel() <= Level.DEBUG:
                # NOTE: THIS IS VERY LENGTHY LOGGING
                print(f"lineno={last.lineno}")
                print(f"filename={last.filename}")
                print(f"name={last.name}")

            record.lineno = last.lineno
            record.pathname = last.filename
            record.funcName = last.name
            title = output
            relatime = True
            output = f"{record.exc_info[1]} {repr(record.exc_info[0])}"
            stack_trace = trace

        if stack_trace is not False:
            output += f"\n{clear}" + self.formatStack(stack_trace).replace(
                "\n", f"\n{clear}{' '*len(prependtime)}").rstrip(
                    f"\n{clear}") + f"{eol}{clear}"

        if relatime is True:  # add relative timestamp
            s = record.relativeCreated // 1000
            m = f"{int(s // 60 % 60):0>2}m" if s >= 60 else ""
            h = str(int(s // 3600)) + "h" if s >= 3600 else ""
            s = str(int(s % 60)) + "s"
            prependtime = f"[{h:>4} {m:>3} {s:0>3}] "
        """ handle context """
        if context:
            if context == LogContextStatus.OPENING:
                context_marker = self.COLOR_CONTEXT_MARKER + f" START {title} ".center(
                    self.context_marker_width, ">") + f"{clear}"
                closing = heading = False

            elif context == LogContextStatus.CURRENT:
                # NOTE(erichiller) UNSURE OF WHAT TO DO WITH PREPEND RIGHT NOW
                # prepend   = "\t"
                # prepend = "↳"
                closing = heading = False
            elif context == LogContextStatus.CLOSING:
                closing = heading = False
                context_marker = self.COLOR_CONTEXT_MARKER + f" END {title} ".center(
                    self.context_marker_width, "<") + f"{clear}"
            if record.msg is None:
                return context_marker

        if 'title' in record.args and record.args['title'] not in (
                None, False):  # add user provided title
            title = f" {record.args['title']} {title}"
        if closing:
            output = (
                f"{output}" + "\n" +  # add an END OF BLOCK marker
                f" END {title} ".center(self.column_name_width, "<"))
        if heading is not False or table is not False:  # this has been marked as a heading so give it some flourish
            if len(title) in (0, 1, 2) and table is True:
                title = " Table "
            title = (title if len(title) > 0 and title[0] == " " else
                     (f" {title} " if len(title.strip()) > 0 else "")).center(
                         self.column_name_width - len(prepend), '>') + "\n"

        # determine color level, Python has no switch statement
        if record.levelno >= Level.CRITICAL:  # set color
            color = self.COLOR_CRITICAL
            flag_location = True
        elif record.levelno >= Level.WARNING:  # set color
            color = self.COLOR_WARNING
            flag_location = True
        elif record.levelno >= Level.NOTICE:
            color = self.COLOR_NOTICE
        elif record.levelno == Level.DEBUG:
            color = self.COLOR_DEBUG
        elif record.levelno == Level.TRACE:
            color = self.COLOR_TRACE
        else:
            color = self.COLOR_DEFAULT

        if level_print != "":
            title = (level_print + title).ljust(  # add level
                self.column_name_width - len(prepend) - len(prependtime))
        if title != "" and title[-1] != "\n":
            title = title + ": "
        if len(title) > 0 and title[0].isspace(
        ):  # strip any whitespace on left
            title = title.lstrip()
            if ":" in title:  # run a check just to see if it should be added back in
                title = "".join(title.rsplit(
                    ":", 1)).ljust(self.column_name_width - len(prepend) -
                                   len(prependtime))
                title = title + ": "
        if flag_location:
            location_color = self.COLOR_LOCATION if self.color else ""
            location = location_color + self.caller_location_string(
                record) + f"{eol}\n{clear}"
        if self.color is False: eol = color = clear = ""
        highlight_color = color if highlight_color == "" else highlight_color
        # used below llne purely for debugging what was my logs and what wasn't
        # else: color = f"{self.ANSI_BG_MAGENTA}{color}"
        return ((
            context_marker +
            ((f"{self.COLOR_EMPHASIS if self.color else ''}" +
              ('▼' * self.console_width) + clear) if emphasis else '') +
            f"{color}{prependtime}{location}{highlight_color}{prepend}{title}{clear}{color}{output}{eol}{clear}"
        ).replace(f"\n{clear}", f"{eol}{clear}\n").replace(
            "\n", f"\n{' ' * len(prependtime)}") +
                (('\n' + f"{self.COLOR_EMPHASIS if self.color else ''}" +
                  ('▲' * self.console_width) + clear) if emphasis else ''))
Пример #18
0
 def filter(self, record: logging.LogRecord) -> bool:
     """Filter the record"""
     # have to sniff the msg and args values of the LogRecord
     record.msg = self.replace(record.getMessage())
     record.args = {}
     return True
Пример #19
0
    def rewrite_record(record: logging.LogRecord):
        if not BraceFormatStyleFormatter.is_brace_format_style(record):
            return

        record.msg = record.msg.format(*record.args)
        record.args = []
Пример #20
0
 def format(self, record: LogRecord) -> str:
     record.name = self._shorten_module_name(record.name)
     record.args = self._redact_logging_args(record.args)
     return super().format(record)