Информация об идентификаторе процесса 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)?
Спасибо за вашу помощь
3 ответа
Вы можете добавить любые свойства, которые вы хотите в GlobalContext. Я использую этот контекст для хранения идентификатора процесса, например:
log4net.GlobalContext.Properties["pid"] = Process.GetCurrentProcess().Id;
Затем вы ссылаетесь на это свойство у своего аппендера, используя обычный шаблон, например:
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %property{pid} %level %logger - %message%newline" />
</layout>
Вы можете добавить столько свойств, сколько захотите, но из-за своей глобальной природы, это работает лучше всего для свойств, которые не изменяются во время выполнения вашего приложения.
Вы можете передать PatternString в PatternLayout:
<layout type="log4net.Layout.PatternLayout">
<conversionPattern type="log4net.Util.PatternString" value="%processid" />
</layout>
Очевидно, PatternString можно использовать только для создания имен журналов (т. Е. Имен файлов и т. Д.), Тогда как макет позволяет форматировать реальное сообщение, которое попадает в журнал. Если в макете процесса нет встроенного шаблона для идентификатора процесса, его можно легко добавить. Это намного проще, чем создавать весь макет.
Вот как это сделать:
Создайте свой собственный конвертер шаблонов (пример ниже пытается получить имя приложения независимо от того, win или web):
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
макет очень тяжелый и может привести к снижению производительности вашего приложения при частом использовании.