Подтвердить что ты не робот

Идентификатор процесса 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)?

Спасибо за помощь

4b9b3361

Ответ 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, поскольку он очень тяжелый, и может сильно снизить производительность вашего приложения.