Ведение журнала базы данных log4net с пользовательскими параметрами

У меня есть ведение журнала базы данных с помощью AdoNetAppender. Что я хотел бы сделать, так это регистрировать идентификатор пользователя в каждом операторе журнала. Однако я не хочу использовать стандартный параметр log4net %identity по двум причинам:

  1. log4net предупреждает, что он очень медленный, так как должен искать идентификатор контекста.
  2. В некоторых сервисных компонентах стандартным удостоверением является учетная запись службы, но мы уже зафиксировали удостоверение пользователя в переменной, и я хотел бы использовать это.

Я видел код, в котором некоторые люди используют log4net.ThreadContext для добавления дополнительных свойств, но я понимаю, что это «небезопасно» из-за чередования потоков (, а также снижает производительность ).

Мой подход заключался в расширении класса AdoNetAppenderParameter таким образом:

public class UserAdoNetAppenderParameter : AdoNetAppenderParameter
{

    public UserAdoNetAppenderParameter()
    {
        DbType = DbType.String;
        PatternLayout layout = new PatternLayout();
        Layout2RawLayoutAdapter converter = new Layout2RawLayoutAdapter(layout);
        Layout = converter;
        ParameterName = "@username";
        Size = 255;
    }


    public override void Prepare(IDbCommand command)
    {            
        command.Parameters.Add(this);
    }


    public override void FormatValue(IDbCommand command, LoggingEvent loggingEvent)
    {            
        string[] data = loggingEvent.RenderedMessage.Split('~');
        string username = data[0];
        command.Parameters["@username"] = username;
    }

}

а затем программно добавьте это к текущему добавлению, например:

ILog myLog = LogManager.GetLogger("ConnectionService");
IAppender[] appenders = myLog.Logger.Repository.GetAppenders();
AdoNetAppender appender = (AdoNetAppender)appenders[0];                    

appender.AddParameter(new UserAdoNetAppenderParameter());

myLog.InfoFormat("{0}~{1}~{2}~{3}", userName, "ClassName", "Class Method", "Message");

Намерение здесь состоит в том, чтобы использовать стандартный формат для сообщений и анализировать первую часть строки, которая всегда должна быть именем пользователя. Затем метод FormatValue ()пользовательского параметра добавления должен использовать только ту часть строки, чтобы ее можно было записать в отдельное поле в базе данных журнала.

Моя проблема в том, что в базу данных не записываются операторы журнала. Как ни странно, при отладке точка останова в методе FormatValue ()срабатывает только тогда, когда я останавливаю службу.

Я просмотрел множество материалов, связанных с этим, но пока не нашел ответов. Кому-нибудь удалось это сделать, или я ошибаюсь. P.S. Я также пытался расширить AdoNetAppender, но он не дает вам доступа для установки значений параметров.

8
задан John J Smith 13 July 2012 в 20:17
поделиться