Log4net: протоколирование двух сообщений в одной строке в базе данных?

102
11

Я пытаюсь зарегистрировать вход и выход конкретного метода в базу данных. Я хотел бы иметь эту информацию в отдельных столбцах. Я исследовал PatternLayout и кажется, что он обслуживает только один параметр сообщения%, что означает, что если вы выполните:


log.Debug("This is a message");

тогда log4net видит "Это сообщение" в качестве сообщения для регистрации. Я хочу сделать что-то вроде:


log.Debug(request, response);

Возможно ли это с помощью log4net? Имейте в виду, что моя цель - иметь "запрос" и "ответ" в столбцах отдельно.

спросил(а) 2021-01-19T19:19:50+03:00 9 месяцев назад
1
Решение
91

Ваш путь PatternConverter - это шаг в правильном направлении, хотя использование статических свойств ввода и вывода делает его немного шатким (с точки зрения безопасности).


Трюк здесь заключается в том, чтобы понять, что параметр message на logger.Debug(...) является объектом и что вы можете передавать все, что захотите.


Вы можете определить тип настраиваемого сообщения


public class InputOutput
{
public string Input {get;set;}
public string Output {get;set;}
}

а затем пусть ваши преобразователи прочитают либо свойство


public class InputPatternConverter : PatternConverter
{
protected override void Convert(System.IO.TextWriter writer, object state)
{
var msg = ((LoggingEvent)state).MessageObject as InputOutput;
if (msg != null)
writer.Write(msg.Input);
}
}

public class OutputPatternConverter : PatternConverter
{
protected override void Convert(System.IO.TextWriter writer, object state)
{
var msg = ((LoggingEvent)state).MessageObject as InputOutput;
if (msg != null)
writer.Write(msg.Output);
}
}


каротаж становится намного чище

logger.Debug(new InputOutput { Input = ..., Output = ...});

Ваша конфигурация будет одинаковой.


Кончик, однако, заключается в подклассе PatternLayout и добавлении преобразователей в конструктор этого класса. Таким образом, вы также можете настроить свою конфигурацию. Это не приведет к тому, что вы потеряете токен% message, ваши токены% input и% output будут добавлены в дополнение ко всем маркерам, которые поддерживает PatternLayout. Таким образом, у вас может быть такой шаблон:


"%date %message %newline%newline %input %newline%newline %output

Здесь выполняется быстрая реализация шаблона пользовательского шаблона:


public class InputOutputPatternLayout : PatternLayout
{
public InputOutputPatternLayout()
{
AddConverter("input", typeof(InputPatternConverter));
AddConverter("output", typeof(OutputPatternConverter));
}
}

ответил(а) 2021-01-19T19:19:50+03:00 9 месяцев назад
47

Я придумал один способ сделать это, используя пользовательские PatternConverters


public class InputPatternConverter : PatternConverter
{
private static string _input;

public static string Input
{
get { return _input; }
set { _input = value; }
}

protected override void Convert(System.IO.TextWriter writer, object state)
{
writer.Write(Input);
}
}

public class OutputPatternConverter : PatternConverter
{
private static string _output;

public static string Output
{
get { return _output; }
set { _output = value; }
}

protected override void Convert(System.IO.TextWriter writer, object state)
{
writer.Write(Output);
}
}


Спецификация агента:

<appender name="ADONetAppender" type="log4net.Appender.AdoNetAppender">
<bufferSize value="1" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<connectionString value="data source=servername;initial catalog=database;Integrated Security=SSPI;" />
<commandText value="INSERT INTO RequestLog ([input], [output]) VALUES (@input, @output)" />
<parameter>
<parameterName value="@input" />
<dbType value="String" />
<size value="4000" />
<layout type="log4net.Layout.PatternLayout">
<converter>
<name value="input" />
<type value="InputPatternConverter, ApplicationName" />
</converter>
<conversionPattern value="%input" />
</layout>
</parameter>
<parameter>
<parameterName value="@output" />
<dbType value="String" />
<size value="4000" />
<layout type="log4net.Layout.PatternLayout">
<converter>
<name value="output" />
<type value="OutputPatternConverter, ApplicationName" />
</converter>
<conversionPattern value="%output" />
</layout>
</parameter>
</appender>

Назовите его, используя:


InputPatternConverter.Input = inputString;
OutputPatternConverter.Output = outputString;

XmlConfigurator.Configure();
ILog logger = LogManager.GetLogger(typeof(ApplicationClassName));
logger.Debug("");

ответил(а) 2021-01-19T19:19:50+03:00 9 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема