Извлечение журналов C# в Python
Я построил библиотеку python, которая использует код C# (который строится и хранится как dll), используя pythonnet. В этой библиотеке я создаю журналы с помощью python logger.
Mylibrary.py
logger = logging.getLogger('mylibrary')
logger.info('logging from my library')
Корневой регистратор настраивается из пользовательского кода. Например, обработчики для корневого регистратора устанавливаются пользователем с помощью метода logger " addhandler ()", задающего формат, выходной файл и т. д. В моей библиотеке я просто регистрируюсь (logger.info ()...) без настройки чего-либо и корневой обработчик, установленный пользователем, заботится о записи этого в файл.
Usercode.py
root_logger = getLogger()
root_logger.addHandler(FileHandler('abc.log'))
root_handler.setFormat(...)
Пользователь может управлять тем, что моя библиотека может регистрировать, установив уровень регистратора, используемого моей библиотекой. Строка ниже в usercode.py устанавливает уровень ведения журнала регистратора моей библиотеки на критический, чтобы библиотека не могла регистрировать что-либо ниже него (logger.info() не попадет в abc.бревно).
getLogger('mylibrary').setLevel(CRITICAL)
Проблема возникает сейчас. Так как я использую C# код в моем библиотека,
- я хочу захватить журналы C# в abc.log
- я также хочу настроить журнал C# так же, как я сделал это для журналов python
Итак, линия
getLogger('mylibrary').setLevel(CRITICAL)
В usercode.py теперь следует убедиться, что в abc попадают только критические журналы как в python, так и в C#.log
Есть ли способ достичь этого?1 ответ:
Нет, вы не можете войти из Python и C# одновременно в один и тот же файл. Причина этого заключается в том, что ведение журнала Python (и, вероятно, c# logging тоже) не оборудовано для одновременного ведения журнала - даже если файл журнала не "заблокирован" одним из них, есть шанс получить разные журналы, смешанные вместе из-за нескольких писателей.
Если вы не являетесь владельцем библиотеки dll C#, вам, вероятно, не повезло - если это не позволит вам настроить файл журнала / уровень из программы C#, нет магия, которую питон может сделать, чтобы исправить это. Однако, если вы управляете исходным кодом и можете построить новую dll, рассмотрите возможность изменения класса C#, чтобы позволить вам передать делегат/лямбда (предполагая, что это реализовано в PythonNet), который просто вызовет обратно в функцию logger Python.
Пример:
C# код:
public class CoolImportedFeature { private readonly Action<string> LogCallback; public CoolImportedFeature(string inputA, int inputB, Action<string, string> logCallback) { LogCallback = logCallback; // do other constructor stuff } public void SomeMethod() { // do something LogCallback("critical", "An error occurred"); } }
Код Python:
def log_callback(log_level, message): getattr(logger, log_level)(message) import CoolImportedFeature feat = CoolImportedFeature("hello", 1, log_callback) feat.SomeMethod()
Что - то вроде этого-нет никакого волшебного перевода между уровнями журнала Python и C#, поэтому вам нужно будет сделать там какой-то перевод (или отражение getattr, которое я использовал выше).