Извлечение журналов 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# код в моем библиотека,

  1. я хочу захватить журналы C# в abc.log
  2. я также хочу настроить журнал C# так же, как я сделал это для журналов python

Итак, линия

getLogger('mylibrary').setLevel(CRITICAL) 

В usercode.py теперь следует убедиться, что в abc попадают только критические журналы как в python, так и в C#.log

Есть ли способ достичь этого?
1 3

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, которое я использовал выше).