def _color_record_traceback(self, record: LogRecord) -> LogRecord: if record.exc_info: # Cache the traceback text to avoid converting it multiple times # (it's constant anyway) if not record.exc_text: record.exc_text = self.formatException(record.exc_info) if record.exc_text: record.exc_text = colored(record.exc_text, DEFAULT_COLORS["ERROR"]) return record
def _color_record_traceback(self, record: LogRecord) -> LogRecord: if record.exc_info: # Cache the traceback text to avoid converting it multiple times # (it's constant anyway) if not record.exc_text: record.exc_text = self.formatException(record.exc_info) if record.exc_text: record.exc_text = self.color(self.log_colors, record.levelname) + \ record.exc_text + escape_codes['reset'] return record
def format(self, record: logging.LogRecord) -> str: record.funcName: str = html.escape(record.funcName) record.name: str = html.escape(record.name) record.msg: str = html.escape(str(record.msg)) record.message = record.getMessage() if self.usesTime(): record.asctime = self.formatTime(record, self.datefmt) record.exc_text = str() if record.exc_info: record.exc_text = self.formatException(record.exc_info) return self.formatMessage(record)
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)
def format(self, record: logging.LogRecord): if isinstance(record.msg, dict): if hasattr(record, 'data'): record.data.update(record.msg) record.message = None else: record.message = record.getMessage() if record.message is not None and 'messageFormatted' not in self._skip_fields_calculation: if self.usesTime(): record.asctime = self.formatTime(record, self.datefmt) record.messageFormatted = self.formatMessage(record) if record.exc_info: record.exceptionClass = record.exc_info[0].__name__ record.exceptionMessage = str(record.exc_info[1]) # Cache the traceback text to avoid converting it multiple times (it's constant anyway) if not record.exc_text and 'exc_text' not in self._skip_fields_calculation: record.exc_text = self.formatException(record.exc_info) json_data = record.__dict__ del json_data['msg'], json_data['args'] # We can't serialize exc_info to JSON by default thus drop it. del json_data['exc_info'] for field in self._drop_fields_from_json: if field in json_data: del json_data[field] return json.dumps(json_data, **self._json_dumps_args)
def format(self, record: logging.LogRecord): """ Format the specified record as text. This implementation is directly copied from the superclass, only adding the codeblock to the traceback. """ record.message = clean_content(record.getMessage()) if self.usesTime(): record.asctime = self.formatTime(record, self.datefmt) s = self.formatMessage(record) if record.exc_info: # Cache the traceback text to avoid converting it multiple times # (it's constant anyway) if not record.exc_text: record.exc_text = self.formatException(record.exc_info) if record.exc_text: if s[-1:] != "\n": s = s + "\n" # add a codeblock so the DiscordHandler can properly split # the error into multiple messages if needed s = f'{s}```py\n{record.exc_text}```' if record.stack_info: if s[-1:] != "\n": s = s + "\n" s = s + self.formatStack(record.stack_info) return s
def format(self, record: logging.LogRecord): # Change it so we save the initial string (without extras), and are not reliant on implementation record.message = record.getMessage() msg = record.message if self.usesTime(): record.asctime = self.formatTime(record, self.datefmt) initial_str = self.formatMessage(record) s = initial_str if record.exc_info: # Cache the traceback text to avoid converting it multiple times # (it's constant anyway) if not record.exc_text: record.exc_text = self.formatException(record.exc_info) if record.exc_text: if s[-1:] != "\n": s = s + "\n" s = s + record.exc_text if record.stack_info: if s[-1:] != "\n": s = s + "\n" s = s + self.formatStack(record.stack_info) # Replace newlines with indentation header_length = 0 if initial_str.endswith(msg): header_length = len(initial_str) - len(msg) replace_str = '\n' + ' ' * header_length if header_length >= 2: replace_str = replace_str[:-2] + '| ' s = s.replace('\n', replace_str) return s
def format(self, record: logging.LogRecord): """ Format the specified record as text. This implementation is directly copied from the superclass, only adding the codeblock to the traceback. """ record.message = clean_content(record.getMessage()) if self.usesTime(): record.asctime = self.formatTime(record, self.datefmt) s = self.formatMessage(record) if record.exc_info: # Cache the traceback text to avoid converting it multiple times # (it's constant anyway) if not record.exc_text: record.exc_text = self.formatException(record.exc_info) if record.exc_text: if s[-1:] != "\n": s = s + "\n" # add a codeblock so the DiscordHandler can properly split the error into multiple messages if needed s = f'{s}```py\n{record.exc_text}```' if record.stack_info: if s[-1:] != "\n": s = s + "\n" s = s + self.formatStack(record.stack_info) return s
def format(self, record: logging.LogRecord) -> str: # noqa ignore=A003 record.indent = '' record.message = record.getMessage().split('\n') s = '' for i in record.message: if len(i.strip()) > 0: msg = ' ' * 10 + '| ' + i if len(record.message) > 1 else i if self.has_time: format_time = f'[{self.formatTime(record, "%Y-%m-%d %H:%M:%S")}]' level = record.levelname.ljust(8) else: format_time = '' level = '' s += f'{format_time} {level} {record.indent} {msg}\n' s = s[:-1] if record.exc_info: # Cache the traceback text to avoid converting it multiple times # (it's constant anyway) if not record.exc_text: exc_text = self.formatException(record.exc_info) record.exc_text = self.format_exception_better(exc_text) if record.exc_text: if s[-1:] != '\n': s += '\n' s = s + record.exc_text if record.stack_info: if s[-1:] != '\n': s += '\n' s = s + self.formatStack(record.stack_info) return s
def format(self, record: LogRecord) -> Dict[str, str]: record.message = record.getMessage() record.levelname_lower = record.levelname.lower() # in the case that no formatter have been provided return an empty dictionary if len(self._formatters) == 0: return dict() # use one of the formatter to set some attribute in the record formatter = self._formatters[list(self._formatters.keys())[0]] if self._uses_time: record.asctime = formatter.formatTime(record=record) if record.exc_info: # Cache the traceback text to avoid converting it multiple times # (it's constant anyway) if not record.exc_text: record.exc_text = formatter.formatException(record.exc_info) key_values_message = self._format_message(record=record) key_values_exception = self._format_exception(record=record) # merge the key-values of the message and the exception such that the message key-values overwrite the # exception key-values incase of duplicates return {**key_values_exception, **key_values_message}
def format(self, record: logging.LogRecord) -> str: """ Format the specified record as text. The record's attribute dictionary is used as the operand to a string formatting operation which yields the returned string. Before formatting the dictionary, a couple of preparatory steps are carried out. The message attribute of the record is computed using LogRecord.getMessage(). If the formatting string uses the time (as determined by a call to usesTime(), formatTime() is called to format the event time. If there is exception information, it is formatted using formatException() and appended to the message. """ if record.levelno == logging.DEBUG: self._fmt = self.dbg_fmt elif record.levelno == logging.INFO: self._fmt = self.info_fmt else: self._fmt = self.default_fmt self._style = logging.PercentStyle(self._fmt) record.message = record.getMessage() if self.usesTime(): record.asctime = self.formatTime(record, self.datefmt) s = self.formatMessage(record) if record.exc_info: # Cache the traceback text to avoid converting it multiple times # (it's constant anyway) if not record.exc_text: record.exc_text = self.formatException(record.exc_info) return s
def emit(self, record: logging.LogRecord) -> None: message = "(unknown)" try: self.format(record) message = record.message asyncio.run_coroutine_threadsafe( coro=self._async_emit( name=record.name, level=record.levelno, # OpenSplice requires latin-1 (utf-8 doesn't work). message=record.message.encode("utf-8", "replace").decode( "latin-1", "replace"), traceback=("" if record.exc_text is None else record.exc_text.encode( "utf-8", "replace").decode( "latin-1", "replace")), filePath=record.pathname, functionName=record.funcName, lineNumber=record.lineno, process=0 if record.process is None else record.process, ), loop=self.loop, ) except Exception as e: print( f"SalLogHandler.emit of level={record.levelno}, " f"message={message!r} failed: {e!r}", file=sys.stderr, ) finally: # The Python formatter documentation suggests clearing ``exc_text`` # after calling ``format`` to avoid problems with # multiple formatters that have different exception formats. record.exc_text = ""
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)
def get_exc_info(record: logging.LogRecord, formatter: logging.Formatter) -> typing.Union[str, None]: if record.exc_text: val = record.exc_text elif record.exc_info: val = formatter.formatException(record.exc_info) record.exc_text = val else: val = None # type: ignore return val
def test_description(self, mocker): from logging import LogRecord requests = mocker.patch("opsgenie_logger.requests") handler = OpsGenieHandler("", "") record = LogRecord("", 0, "", 0, "", [], None) record.exc_text = "bad thing happened" handler.emit(record) calls = requests.post.call_args_list kwargs = calls[0][1] payload = kwargs["json"] assert payload["description"] == "\nbad thing happened"
def emit(self, record: logging.LogRecord) -> None: """ Records the log message. """ # Remove `exc_info` to reclaim memory. if record.exc_info: if not record.exc_text: record.exc_text = ''.join(format_exception(*record.exc_info)) record.exc_info = None self._records.append(record) self.max_level_emitted = max(self.max_level_emitted, record.levelno)
def format_message(self, record: logging.LogRecord): # noqa: C901 s = record.getMessage() if record.exc_info: # Cache the traceback text to avoid converting it multiple times # (it's constant anyway) if not record.exc_text: record.exc_text = self.formatException(record.exc_info) if record.exc_text: if s[-1:] != '\n': s = s + '\n' s = s + record.exc_text if record.stack_info: if s[-1:] != '\n': s = s + '\n' s = s + self.formatStack(record.stack_info) return s
def _format_exception_details(self, record: logging.LogRecord) -> str: s = "" if record.exc_info: # Cache the traceback text to avoid converting it multiple times # (it's constant anyway) if not record.exc_text: record.exc_text = self._format_exception(record.exc_info) if record.exc_text: if s[-1:] != "\n": s = s + "\n" s = s + record.exc_text if record.stack_info: if s[-1:] != "\n": s = s + "\n" s = s + record.stack_info return s
def emit(self, record: logging.LogRecord) -> None: """ :param record: :return: """ try: kodi_level = Logger.get_kodi_level(record.levelno) if record.exc_info is not None: ignore_frames = record.__dict__.get('ignore_frames', 0) + 4 msg = self.formatter.formatException(record.exc_info, ignore_frames) record.exc_text = msg msg = self.format(record) xbmc.log(msg, kodi_level) except Exception as e: pass
def formatTraceback(self, record: logging.LogRecord) -> Optional[str]: exc = "" if record.exc_info: # Cache the traceback text to avoid converting it multiple times # (it's constant anyway) if not record.exc_text: record.exc_text = self.formatException(record.exc_info) if record.exc_text: if exc[-1:] != "\n": exc += "\n" exc += record.exc_text if record.stack_info: if exc[-1:] != "\n": exc += "\n" exc += self.formatStack(record.stack_info) exc = exc.lstrip("\n").replace("\n", "<br>") return None if not exc else exc
def format(self, record: LogRecord) -> str: record.message = re.sub(RICH_FORMAT_REGEX, "", record.getMessage()) if self.usesTime(): record.asctime = self.formatTime(record, self.datefmt) s = self.formatMessage(record) if record.exc_info: # Cache the traceback text to avoid converting it multiple times # (it's constant anyway) if not record.exc_text: record.exc_text = self.formatException(record.exc_info) if record.exc_text: if s[-1:] != "\n": s = s + "\n" s = s + record.exc_text if record.stack_info: if s[-1:] != "\n": s = s + "\n" s = s + self.formatStack(record.stack_info) return s
def format(self, record: logging.LogRecord): now = datetime.now(tz=self._tz) data = dict( context=self._context, name=self._name, message=record.getMessage(), level=record.levelname, date=now, color_start="", color_end="", ) if self._terminal: data['color_start'] = TerminalColor.for_level(record.levelno) if data['color_start']: data['color_end'] = colorama.Style.RESET_ALL s = ( "{context}/{name}" " [{date:%Y-%m-%d %H:%M:%S %z}]" " {color_start}| " "{level:{level_name_length}}" " | {message}" "{color_end}" ).format(level_name_length=self._max_logging_level_length, **data) if record.exc_info: # Cache the traceback text to avoid converting it multiple times # (it's constant anyway) if not record.exc_text: record.exc_text = self.formatException(record.exc_info) if record.exc_text: if s[-1:] != "\n": s += "\n" s = s + record.exc_text if record.stack_info: if s[-1:] != "\n": s += "\n" s = s + self.formatStack(record.stack_info) return s
def format(self, record: logging.LogRecord) -> str: """ Applies the desired format to a string passed to one of the log messages. Parameters ---------- record: logging.LogRecord Data structure containing various log parameters. Returns ------- str String with applied format and theme """ record.message = record.getMessage() level = color_text(record.levelname, self.theme.level_color[record.levelname]) s = "%s.%03d :: %+50s :: %-4s :: %-19s | %s " % ( self.formatTime(record, AlignedColorFormatter.datefmt), record.msecs, record.name, record.lineno, level, self.theme.prompt[record.levelname], ) s += color_text(record.message, self.theme.text_color[record.levelname]) if record.exc_info: # Cache the traceback text to avoid converting it multiple times # (it's constant anyway) if not record.exc_text: record.exc_text = self.formatException(record.exc_info) if record.exc_text: if s[-1:] != "\n": s = s + "\n" s = s + record.exc_text return s
def emit(self, record: logging.LogRecord): # CloudLogging list of supported log levels is a superset of python logging level names cl_log_level = record.levelname json = { 'message': record.getMessage(), 'name': record.name, 'filename': record.filename, 'module': record.module, 'lineno': record.lineno, } # mimic caching behaviour of `logging.Formatter.format` # render/cache exception info in the same way as default `logging.Formatter` if record.exc_info and not record.exc_text: record.exc_text = self._format_exception(record.exc_info) if record.exc_text: json['exc_text'] = str(record.exc_text) if record.stack_info: json['stack_info'] = str(record.stack_info) self.write_log_entries(json, cl_log_level)
def format(self, record: LogRecord): record.exc_text = '' return super().format(record)
def format(self, record: logging.LogRecord) -> str: """Remove cached exception traceback message.""" # Clear cached exception message record.exc_text = '' return super(NoExceptionFormatter, self).format(record)
def filter(record: logging.LogRecord) -> bool: """Removes exception stack traces information.""" record.exc_info = None record.exc_text = None # type: ignore return True
def format(self, record: LogRecord) -> str: if record.exc_text: # jank way to color the stacktrace but will do for now record.exc_text = colored(record.exc_text, color='grey', attrs=['bold']) return self.formatters.get(record.levelno).format(record)