Идентификатор процесса log4net
Я пытаюсь создать решение для регистрации, которое включает несколько процессов на нескольких машинах. Я планировал использовать UDPAppender для отправки всех сообщений журнала на одну машину, которая будет управлять ими. У меня есть несколько вопросов о patternstrings vs patternlayouts.
Поскольку мне нужно знать, какой из машин и какой процесс вышло из сообщения журнала, я хочу включить его в журнал. Я нашел% property {log4net: HostName} для имени хоста, и это отлично работает. Однако я не вижу ничего для идентификатора процесса в PatternLayouts. Я, конечно, вижу что-то подобное в PatternString. Из FAQ:
<appender name="LogFileAppender" type="log4net.Appender.FileAppender">
<file type="log4net.Util.PatternString" value="log-file-[%processid].txt" />
<layout type="log4net.Layout.PatternLayout" value="%date [%thread] %-5level %logger - %message%newline" />
</appender>
Но я не уверен, что или как смешивать и сопоставлять два (или даже если это канонический способ сделать это).
Итак, мои вопросы:
-
В чем разница между PatternString и PatternLayout? Почему оба?
-
Я вижу% processid в PatternString, как мне получить то же самое в PatternLayout? Вот мой тестовый макет:
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] [%property{log4net:HostName}] %-5level %logger - %message%newline" />
</layout>
-
Наконец, имеет смысл использовать макет XML для UDP-приложения. Похоже, что XmlLayoutSchemaLog4j уже добавляет HostNameProperty в XML-сообщение. Если я не хочу добавить этот новый идентификатор процесса (и, возможно, имя процесса) в XML-сообщение, что это лучший способ сделать это? Должен ли я просто скопировать src\Layouts\XmlLayoutSchemaLog4j.cs, изменить его и сообщить log4net, что я создал этот новый макет (например, SampleLayoutsApp)?
Спасибо за помощь
Ответы
Ответ 1
Вы можете добавить любые свойства, которые хотите использовать в GlobalContext. Я использую этот контекст для хранения идентификатора процесса, например:
log4net.GlobalContext.Properties["pid"] = Process.GetCurrentProcess().Id;
Затем вы ссылаетесь на это свойство из своего приложения, используя обычный шаблон, например:
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %property{pid} %level %logger - %message%newline" />
</layout>
Вы можете добавить столько свойств, сколько хотите, но из-за его глобального характера он лучше всего подходит для свойств, которые не изменяются во время выполнения вашего приложения.
Ответ 2
Вы можете комбинировать PatternString с PatternLayout:
<layout type="log4net.Layout.PatternLayout">
<conversionPattern type="log4net.Util.PatternString" value="%processid" />
</layout>
Ответ 3
Очевидно, что PatternString может использоваться только для создания имен журналов (например, имен файлов и т.д.), тогда как макет позволяет отформатировать фактическое сообщение, которое попадает в журнал. Если в макете процесса нет встроенного шаблона для идентификатора процесса, вы можете легко добавить его. Это намного проще, чем создание всего макета.
Вот как это сделать:
Создайте собственный собственный конвертер шаблонов (пример ниже пытается получить имя приложения независимо от того, выиграет он или сеть):
internal sealed class ApplicationNamePatternConverter : PatternLayoutConverter
{
/// <summary>
/// Write the event application name to the output
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
string name = string.Empty;
if( System.Web.HttpContext.Current != null )
{
string[] applicationPath = System.Web.HttpContext.Current.Request.ApplicationPath.Split('/');
name = applicationPath[applicationPath.Length - 1];
}
else
{
if( System.Reflection.Assembly.GetEntryAssembly() != null )
{
name = System.Reflection.Assembly.GetEntryAssembly().GetName().Name;
}
}
writer.Write(name);
}
}
Добавьте запись для вашего конвертера в реестр класса PatternLayout
static PatternLayout()
{
...
s_globalRulesRegistry.Add("ApplicationName", typeof(ApplicationNamePatternConverter));
}
Теперь вы можете использовать %ApplicationName
в значении PatternLayout, чтобы получить то, что вам нужно.
Я бы посоветовал не использовать макет XmlLayoutSchemaLog4j
, поскольку он очень тяжелый, и может сильно снизить производительность вашего приложения.