Как я могу включить относительный путь к модулю в операторе регистрации Python? - PullRequest
0 голосов
/ 01 октября 2018

В моем проекте есть подпакет, вложенный в корневой пакет, например:

  • mypackage/
    • __init__.py
    • topmodule.py
    • subpackage/
      • __init__.py
      • nested.py

Моя цель - войти в системузаписи, отформатированные как:

mypackage/topmodule.py:123: First log message
mypackage/subpackage/nested.py:456: Second log message

, чтобы пути становились кликабельными в моем терминале.


Я пробовал следующие форматы.

  • '%(modulename).pys:%(lineno): %(message)s' не активируется (точки должны быть косыми чертами):

    mypackage.topmodule.py:123: First log message
    mypackage.subpackage.nested.py:456: Second log message
    
  • 'mypackage/%(filename)s:%(lineno): %(message)s' не работает для подпакетов:

    mypackage/topmodule.py:123: First log message
    mypackage/nested.py:456: Second log message
    
  • '%(pathname)s:%(lineno): %(message)s' создает кликабельные пути, но они настолько длинные, что обрезают остальную часть моего журнала:

    /Users/jacebrowning/Documents/mypackage/topmodule.py:123: First log message
    /Users/jacebrowning/Documents/mypackage/subpackage/nested.py:456: Second log message
    

Isесть шаблон регистрации, который я могу передать logging.basicConfig(format='???'), который произведет записи журнала, которые я желаю?

1 Ответ

0 голосов
/ 01 октября 2018

Вам нужно выполнить дополнительную обработку, чтобы получить нужный вам путь.

Вы можете выполнить такую ​​обработку и добавить дополнительную информацию в записи журнала, включая «локальный» путь для вашего собственного пакета,путем создания пользовательского фильтра .

Фильтры на самом деле не имеют для выполнения фильтрации, но они получают доступ ко всем записям журнала, поэтому они являются отличным способомобновления записей с отсутствующей информацией.Просто убедитесь, что вы вернете True когда закончите:

import logging
import os
import sys


class PackagePathFilter(logging.Filter):
    def filter(self, record):
        pathname = record.pathname
        record.relativepath = None
        abs_sys_paths = map(os.path.abspath, sys.path)
        for path in sorted(abs_sys_paths, key=len, reverse=True):  # longer paths first
            if not path.endswith(os.sep):
                path += os.sep
            if pathname.startswith(path):
                record.relativepath = os.path.relpath(pathname, path)
                break
        return True

Это найдет запись sys.path, которая является родительским каталогом для pathname в записи журнала, и добавит новую запись relativepath в журналзапись.Затем вы можете использовать %(relativepath)s, чтобы включить его в свой журнал.

Добавить фильтр в любой обработчик , который вы настроили с помощью пользовательского форматера:

handler.addFilter(PackagePathFilter())

и вместе с '%(relativepath)s:%(lineno)s: %(message)s' в качестве формата ваши сообщения журнала будут выглядеть так:

mypackage/topmodule.py:123: First log message
mypackage/subpackage/nested.py:456: Second log message

(фактический вывод, за исключением того, что я изменил номера строк на этом).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...