def add_code_location_processor(logger, _, event_dict): # Mostly copy/pasta from: # https://stackoverflow.com/questions/54872447/how-to-add-code-line-number-using-structlog # If by any chance the record already contains a `modline` key, # (very rare) move that into a 'modline_original' key if 'modline' in event_dict: event_dict['modline_original'] = event_dict['modline'] f, name = _find_first_app_frame_and_name(additional_ignores=[ "logging", __name__, ]) if not f: return event_dict frameinfo = inspect.getframeinfo(f) if not frameinfo: return event_dict module = inspect.getmodule(f) if not module: return event_dict if frameinfo and module: event_dict['loc'] = '{}:{}'.format( os.path.basename(frameinfo.filename), # module.__name__, ## If you want to add a module name, uncomment this and modify the format above frameinfo.lineno, ) return event_dict
def _show_module_info_processor(logger, method_name, event_dict): """ Get the module, function and line number corresponding to the log message. Derived from https://stackoverflow.com/questions/54872447/how-to-add-code-line-number-using-structlog Args: logger: str - the name of the loggers namespace method_name: str - the name of the function event_dict: dict - the contents fo the log record Returns: The event dict (modified to include the function and line number) """ # If by any chance the record already contains a `call_site` key, # (very rare) move that into a 'call_site_original' key if "call_site" in event_dict: event_dict["call_site_original"] = event_dict["call_site"] f, name = _find_first_app_frame_and_name( additional_ignores=["logging", "src.library.logging"]) if not f: return event_dict frameinfo = inspect.getframeinfo(f) if not frameinfo: return event_dict module = inspect.getmodule(f) if not module: return event_dict if frameinfo and module: event_dict[ "call_site"] = f"{ module.__name__}.{frameinfo.function}:{frameinfo.lineno}" return event_dict
def add_module_and_lineno(logger: logging.Logger, name: str, event_dict: Dict[str, Any]) -> Dict[str, Any]: # see https://github.com/hynek/structlog/issues/253 for a feature request to get this done better frame, module_str = _find_first_app_frame_and_name( additional_ignores=[__name__, 'logging']) event_dict['modline'] = f'{module_str}:{frame.f_lineno}' return event_dict
def add_app_context(_, __, event_dict): from structlog._frames import _find_first_app_frame_and_name f, name = _find_first_app_frame_and_name([__name__]) event_dict['file'] = f.f_code.co_filename event_dict['line'] = f.f_lineno event_dict['function'] = f.f_code.co_name return event_dict
def test_tolerates_missing_name(self, monkeypatch): """ Use ``?`` if `f_globals` lacks a `__name__` key """ f1 = stub(f_globals={}, f_back=None) monkeypatch.setattr(structlog._frames.sys, "_getframe", lambda: f1) f, n = _find_first_app_frame_and_name() assert ((f1, "?") == (f, n))
def test_tolerates_missing_name(self, monkeypatch): """ Use ``?`` if `f_globals` lacks a `__name__` key """ f1 = stub(f_globals={}, f_back=None) monkeypatch.setattr(structlog._frames.sys, "_getframe", lambda: f1) f, n = _find_first_app_frame_and_name() assert ((f1, "?") == (f, n))
def logger_factory(name=None): from structlog._frames import _find_first_app_frame_and_name if name is None: _, name = _find_first_app_frame_and_name(additional_ignores=[ f'{__package__}.logconf', ]) return logbook.Logger(name, level=level)
def test_tolerates_f_back_is_None(self, monkeypatch): """ Use ``?`` if all frames are in ignored frames. """ f1 = stub(f_globals={'__name__': 'structlog'}, f_back=None) monkeypatch.setattr(structlog._frames.sys, "_getframe", lambda: f1) f, n = _find_first_app_frame_and_name() assert ((f1, "?") == (f, n))
def test_tolerates_f_back_is_None(self, monkeypatch): """ Use ``?`` if all frames are in ignored frames. """ f1 = stub(f_globals={'__name__': 'structlog'}, f_back=None) monkeypatch.setattr(structlog._frames.sys, "_getframe", lambda: f1) f, n = _find_first_app_frame_and_name() assert ((f1, "?") == (f, n))
def test_tolerates_name_explicitly_None_oneframe(self, monkeypatch): """ Use ``?`` if `f_globals` has a `None` valued `__name__` key """ f1 = stub(f_globals={'__name__': None}, f_back=None) monkeypatch.setattr(structlog._frames.sys, "_getframe", lambda: f1) f, n = _find_first_app_frame_and_name() assert ((f1, "?") == (f, n))
def _record_module(logger, name, event_dict): """Processor that records the module and line where the logging call was invoked.""" f, name = _find_first_app_frame_and_name( ignores=['structlog', 'inbox.log', 'inbox.sqlalchemy_ext.util', 'inbox.models.session', 'sqlalchemy']) event_dict['module'] = '{}:{}'.format(name, f.f_lineno) return event_dict
def test_tolerates_name_explicitly_None_oneframe(self, monkeypatch): """ Use ``?`` if `f_globals` has a `None` valued `__name__` key """ f1 = stub(f_globals={'__name__': None}, f_back=None) monkeypatch.setattr(structlog._frames.sys, "_getframe", lambda: f1) f, n = _find_first_app_frame_and_name() assert ((f1, "?") == (f, n))
def test_ignores_structlog_by_default(self, monkeypatch): """ No matter what you pass in, structlog frames get always ignored. """ f1 = stub(f_globals={'__name__': 'test'}, f_back=None) f2 = stub(f_globals={'__name__': 'structlog.blubb'}, f_back=f1) monkeypatch.setattr(structlog._frames.sys, '_getframe', lambda: f2) f, n = _find_first_app_frame_and_name() assert ((f1, 'test') == (f, n))
def test_ignores_structlog_by_default(self, monkeypatch): """ No matter what you pass in, structlog frames get always ignored. """ f1 = stub(f_globals={'__name__': 'test'}, f_back=None) f2 = stub(f_globals={'__name__': 'structlog.blubb'}, f_back=f1) monkeypatch.setattr(structlog._frames.sys, '_getframe', lambda: f2) f, n = _find_first_app_frame_and_name() assert ((f1, 'test') == (f, n))
def test_ignoring_of_additional_frame_names_works(self, monkeypatch): """ Additional names are properly ignored too. """ f1 = stub(f_globals={'__name__': 'test'}, f_back=None) f2 = stub(f_globals={'__name__': 'ignored.bar'}, f_back=f1) f3 = stub(f_globals={'__name__': 'structlog.blubb'}, f_back=f2) monkeypatch.setattr(structlog._frames.sys, '_getframe', lambda: f3) f, n = _find_first_app_frame_and_name(additional_ignores=['ignored']) assert ((f1, 'test') == (f, n))
def test_ignoring_of_additional_frame_names_works(self, monkeypatch): """ Additional names are properly ignored too. """ f1 = stub(f_globals={'__name__': 'test'}, f_back=None) f2 = stub(f_globals={'__name__': 'ignored.bar'}, f_back=f1) f3 = stub(f_globals={'__name__': 'structlog.blubb'}, f_back=f2) monkeypatch.setattr(structlog._frames.sys, '_getframe', lambda: f3) f, n = _find_first_app_frame_and_name(additional_ignores=['ignored']) assert ((f1, 'test') == (f, n))
def test_ignoring_of_additional_frame_names_works(self, monkeypatch): """ Additional names are properly ignored too. """ f1 = stub(f_globals={"__name__": "test"}, f_back=None) f2 = stub(f_globals={"__name__": "ignored.bar"}, f_back=f1) f3 = stub(f_globals={"__name__": "structlog.blubb"}, f_back=f2) monkeypatch.setattr(structlog._frames.sys, "_getframe", lambda: f3) f, n = _find_first_app_frame_and_name(additional_ignores=["ignored"]) assert (f1, "test") == (f, n)
def test_ignoring_of_additional_frame_names_works(self, monkeypatch): """ Additional names are properly ignored too. """ f1 = stub(f_globals={"__name__": "test"}, f_back=None) f2 = stub(f_globals={"__name__": "ignored.bar"}, f_back=f1) f3 = stub(f_globals={"__name__": "structlog.blubb"}, f_back=f2) monkeypatch.setattr(structlog._frames.sys, "_getframe", lambda: f3) f, n = _find_first_app_frame_and_name(additional_ignores=["ignored"]) assert (f1, "test") == (f, n)
def test_tolerates_name_explicitly_None_manyframe(self, monkeypatch): """ Use ``?`` if `f_globals` has a `None` valued `__name__` key, multiple frames up. """ f1 = stub(f_globals={"__name__": None}, f_back=None) f2 = stub(f_globals={"__name__": "structlog.blubb"}, f_back=f1) monkeypatch.setattr(structlog._frames.sys, "_getframe", lambda: f2) f, n = _find_first_app_frame_and_name() assert (f1, "?") == (f, n)
def test_tolerates_name_explicitly_None_manyframe(self, monkeypatch): """ Use ``?`` if `f_globals` has a `None` valued `__name__` key, multiple frames up. """ f1 = stub(f_globals={"__name__": None}, f_back=None) f2 = stub(f_globals={"__name__": "structlog.blubb"}, f_back=f1) monkeypatch.setattr(structlog._frames.sys, "_getframe", lambda: f2) f, n = _find_first_app_frame_and_name() assert (f1, "?") == (f, n)
def add_app_context(logger, method_name, event_dict): """Add file, line, and function of log print.""" f, name = _find_first_app_frame_and_name(['logging', __name__]) event_dict['trace'] = { 'file': f.f_code.co_filename, 'line': f.f_lineno, 'build': { 'commit': config.build['commit'] }, 'function': f.f_code.co_name } return event_dict
def findCaller(self, stack_info=False, stacklevel=1): """ Finds the first caller frame outside of structlog so that the caller info is populated for wrapping stdlib. This logger gets set as the default one when using LoggerFactory. """ f, name = _find_first_app_frame_and_name(["logging"]) if stack_info: sinfo = _format_stack(f) else: sinfo = None return f.f_code.co_filename, f.f_lineno, f.f_code.co_name, sinfo
def __call__(self, logger, method_name, event_dict): f, name = _find_first_app_frame_and_name([ "logging", __name__, ]) event_dict['_trace_code'] = '{}:{}:{}'.format( f.f_code.co_filename, f.f_code.co_name, f.f_lineno, ) return event_dict
def add_caller_info(logger, _, event_dict): f, name = _find_first_app_frame_and_name(additional_ignores=["logging", __name__]) if not f: return event_dict frameinfo = inspect.getframeinfo(f) if not frameinfo: return event_dict module = inspect.getmodule(f) if not module: return event_dict if frameinfo and module: event_dict["__module"] = module.__name__ event_dict["__lineno"] = frameinfo.lineno event_dict["__func"] = f.f_code.co_name return event_dict
def findCaller(self, stack_info=False): """ Finds the first caller frame outside of structlog so that the caller info is populated for wrapping stdlib. This logger gets set as the default one when using LoggerFactory. """ f, name = _find_first_app_frame_and_name(['logging']) if PY3: # pragma: nocover if stack_info: sinfo = _format_stack(f) else: sinfo = None return f.f_code.co_filename, f.f_lineno, f.f_code.co_name, sinfo else: return f.f_code.co_filename, f.f_lineno, f.f_code.co_name
def add_log_location_data(logger, method_name, event_dict): record = event_dict.get("_record") if record is not None: event_dict['filepath'] = record.pathname event_dict['module'] = record.module event_dict['function'] = record.funcName event_dict['lineno'] = record.lineno elif logger is not None: from structlog._frames import _find_first_app_frame_and_name frame, _ = _find_first_app_frame_and_name(['logging', __name__]) event_dict['filepath'] = frame.f_code.co_filename event_dict['module'] = frame.f_globals['__name__'] event_dict['function'] = frame.f_code.co_name event_dict['lineno'] = frame.f_lineno return event_dict
def __add_log_source_to_dict(logger, _, event_dict): # If by any chance the record already contains a `source` key, # (very rare) move that into a 'source_original' key if "source" in event_dict: event_dict["source_original"] = event_dict["source"] (frame, name) = _find_first_app_frame_and_name( additional_ignores=["logging", "correlation", "viaa", __name__] ) if not frame: return event_dict filename = inspect.getfile(frame) frameinfo = inspect.getframeinfo(frame) if not frameinfo: return event_dict if frameinfo: event_dict["source"] = "{}:{}:{}".format( filename, frameinfo.function, frameinfo.lineno, ) return event_dict
def __call__(self, *args): """ Deduce the caller's module name and create a stdlib logger. If an optional argument is passed, it will be used as the logger name instead of guesswork. This optional argument would be passed from the :func:`structlog.get_logger` call. For example ``struclog.get_logger('foo')`` would cause this method to be called with ``'foo'`` as its first positional argument. :rtype: `logging.Logger` .. versionchanged:: 0.4.0 Added support for optional positional arguments. Using the first one for naming the constructed logger. """ if args: return logging.getLogger(args[0]) # We skip all frames that originate from within structlog or one of the # configured names. _, name = _find_first_app_frame_and_name(self._ignore) return logging.getLogger(name)
def __call__(self, *args): """ Deduce the caller's module name and create a stdlib logger. If an optional argument is passed, it will be used as the logger name instead of guesswork. This optional argument would be passed from the :func:`structlog.get_logger` call. For example ``structlog.get_logger("foo")`` would cause this method to be called with ``"foo"`` as its first positional argument. :rtype: logging.Logger .. versionchanged:: 0.4.0 Added support for optional positional arguments. Using the first one for naming the constructed logger. """ if args: return logging.getLogger(args[0]) # We skip all frames that originate from within structlog or one of the # configured names. _, name = _find_first_app_frame_and_name(self._ignore) return logging.getLogger(name)
def __add_log_source_to_dict(logger, _, event_dict): try: from celery._state import get_current_task get_current_task = get_current_task except ImportError: get_current_task = lambda: None task = get_current_task() if task and task.request and 'fields' in event_dict: event_dict['fields']['celery_task_id'] = task.request.id event_dict['fields']['celery_task_name'] = task.name if 'task_id' in event_dict: event_dict['correlationId'] = event_dict['task_id'] del event_dict['task_id'] # If by any chance the record already contains a `source` key, # (very rare) move that into a 'source_original' key if 'source' in event_dict: event_dict['source_original'] = event_dict['source'] f, name = _find_first_app_frame_and_name(additional_ignores=[ "logging", __name__ ]) if not f: return event_dict filename = inspect.getfile(f) frameinfo = inspect.getframeinfo(f) if not frameinfo: return event_dict if frameinfo: event_dict['source'] = '{}:{}:{}'.format( filename, frameinfo.function, frameinfo.lineno, ) return event_dict
def add_app_context(logger, method_name, event_dict): f, _ = _find_first_app_frame_and_name(['logging', __name__]) event_dict['file'] = f.f_code.co_filename event_dict['line'] = f.f_lineno event_dict['function'] = f.f_code.co_name return event_dict
def _record_module(logger, name, event_dict): """Processor that records the module and line where the logging call was invoked.""" f, name = _find_first_app_frame_and_name(additional_ignores=['inbox.log']) event_dict['module'] = '{}:{}'.format(name, f.f_lineno) return event_dict
def _sl_processor_add_source_context(_, __, event_dict: Dict) -> Dict: frame, name = _find_first_app_frame_and_name([__name__, 'logging']) event_dict['file'] = frame.f_code.co_filename event_dict['line'] = frame.f_lineno event_dict['function'] = frame.f_code.co_name return event_dict
def __call__(self, logger, name, event_dict): if event_dict.pop('stack_info', None): event_dict['stack'] = _format_stack( _find_first_app_frame_and_name()[0] ) return event_dict
def __call__(self, logger, name, event_dict): if event_dict.pop('stack_info', None): event_dict['stack'] = _format_stack( _find_first_app_frame_and_name()[0]) return event_dict