Использование отдельной log4net для каждой веб-службы / страницы

У меня есть веб-приложение с несколькими веб-службами. Это веб-приложение имеет слой бизнес и постоянство. Можно ли использовать отдельное приложение журнала (файл журнала) для каждой веб-службы?

Это относится и к веб-страницам. По сути, я хочу отделить свои журналы не на основе класса или слоя / пространства имен, а от точки входа, которая может быть веб-службой или веб-страницей.

11.12.2008 23:55:55
4 ОТВЕТА

Вы можете определить, какой регистратор получить в каждом веб-сервисе:

namespace log4net
{
    public class LogManager
    {
        public static ILog GetLogger(string name);
        public static ILog GetLogger(Type type);
    }
}

И тогда в вашем приложении вы можете вызывать каждый регистратор соответствующим образом:

public class MyApp 
{
    // Define a static logger variable so that it references the
    // Logger instance named "MyApp".
private static readonly ILog log = LogManager.GetLogger(typeof(MyApp));

static void Main(string[] args) 
{
    // Set up a simple configuration that logs on the console.
    BasicConfigurator.Configure();

    log.Info("Entering application.");
    Bar bar = new Bar();
    bar.DoIt();
    log.Info("Exiting application.");
}
}

Убедитесь, что вы изменили typeofправильный веб-сервис.

Источник и дополнительная информация здесь .

1
12.12.2008 01:23:06

Gortok, это типичный способ обработки логов. Однако я имею в виду что-то другое, и я думаю, что я не был достаточно ясен в своем вопросе.

Вот гипотетический пример: у нас есть веб-приложение, в котором есть несколько страниц администратора и несколько страниц клиентов, и мы хотим иметь два разных файла admin.log и customer.log для каждого набора страниц. Оба набора страниц используют бизнес-уровень (включая CustomerService, OrderService и т. Д.) И уровень репозитория CustomerRepository, OrderRepository и т. Д.). Все слои и классы в приложении используются на обоих наборах страниц, но мы хотим, чтобы журнал был отдельным. Это облегчает ситуацию, когда на страницах администратора происходит исключение, и вы просматриваете журнал, который важен для отслеживания проблемы. Упомянутое вами решение, которое является типичным способом регистрации вещей, не покрывает эту ситуацию, потому что при использовании typeof (MyApp) (MyApp - это имя класса или пространства имен) не будет указывать, какой аппендер использовать, исходя из того, на какой странице пользователь инициировал свой запрос.

Возможно, один из способов справиться с этой ситуацией - это использовать объект значения домена в приложении и установить его значение для соответствующего регистратора, когда запрос инициируется пользователем на уровне пользовательского интерфейса, и использовать это значение в качестве параметра конструктора, когда вы определяете свой регистратор в каждом из них. учебный класс. Но мне интересно, есть ли лучший способ справиться с этим подходом в log4net, о котором я не знаю.

Теперь мой вопрос прояснился?

0
12.12.2008 14:42:05

Я бы предложил использовать вложенные диагностические контексты (NDC) на каждой странице, а затем отфильтровать выходные данные журнала на основе NDC.

Информация NDC будет включена в события, зарегистрированные в текущем контексте потока, который будет включать код страницы, код службы, код хранилища и т. Д.

Используя фильтрацию содержимого NDC, вы можете отделить вывод журнала от различных сервисов.

1
19.07.2009 21:12:00
РЕШЕНИЕ

Я мог бы сделать это с помощью PropertyFilter. Я определил следующий appender в файле конфигурации:

<appender name="UiFileAppender" type="log4net.Appender.RollingFileAppender">
  <file value="Log1.log" />
  <appendToFile value="true" />
  <rollingStyle value="Size" />
  <maxSizeRollBackups value="10" />
  <maximumFileSize value="5MB" />
  <staticLogFileName value="true" />
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
  </layout>
  <filter type="log4net.Filter.PropertyFilter">
    <Key value="channel"/>
    <StringToMatch value="ui" />
    <AcceptOnMatch value="true" />
  </filter>
  <filter type="log4net.Filter.DenyAllFilter" />
</appender>
<appender name="WsFileAppender" type="log4net.Appender.RollingFileAppender">
  <file value="Log1.log" />
  <appendToFile value="true" />
  <rollingStyle value="Size" />
  <maxSizeRollBackups value="10" />
  <maximumFileSize value="5MB" />
  <staticLogFileName value="true" />
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
  </layout>
  <filter type="log4net.Filter.PropertyFilter">
    <Key value="channel"/>
    <StringToMatch value="ws" />
    <AcceptOnMatch value="true" />
  </filter>
  <filter type="log4net.Filter.DenyAllFilter" />
</appender>

Важной частью вышеуказанного аппендера являются теги. Когда пользователь использует пользовательский интерфейс, я устанавливаю свойство channel в ui, как показано в следующем коде:

log4net.GlobalContext.Properties["channel"] = "ui";

и когда пользователь использует веб-сервисы, я использую следующий код:

log4net.GlobalContext.Properties["channel"] = "ws";

Мне нужно установить свойство «канал» на самом высоком уровне входа, когда запрос инициируется.

0
28.07.2009 18:12:30