log4net, установленный из внешнего файла конфигурации, не работает

У меня странная проблема с log4net.

В приложении ASP.NET я хочу настроить log4net извне, поэтому у меня есть отдельный файл log4net.config, который я подключаю к своему веб-приложению с помощью этой строки в файле AssemblyInfo.cs, принадлежащем моему веб-приложению:

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4Net.config", Watch = true)]

Теперь, если я создам экземпляр класса регистратора log4net обычным способом, например:

public class MyClass
{
    private static readonly ILog _logger = log4net.LogManager.GetLogger(typeof(MyClass));
    ....

Тогда это работает, и ведение журнала работает как обычно. Однако я заключил свой код ведения журнала в класс LogManager, который является частью отдельной сборки (инфраструктуры) и повторно используется в ряде проектов. У него есть GetLogger, который выглядит так:

public static class LogManager
{
    public static ILog GetLogger()
    {
        var stack = new StackTrace();
        var frame = stack.GetFrame(1);
        return new log4net.LogManager.GetLogger(frame.GetMethod().DeclaringType);
    }
}

Поэтому я могу использовать это в моем коде asp.net:

public class MyClass
{
    private static readonly ILog _logger = LogManager.GetLogger();
    ....

Но ... Это не работает! Регистрация не ведется. Похоже, что файл конфигурации подключен неправильно. Если я помещу свою конфигурацию log4net непосредственно в web.config, этот LogManager будет работать нормально.


person Matt Roberts    schedule 22.06.2011    source источник
comment
Сканирует ли Log4Net атрибут сборки, когда он впервые запускается в текущей выполняющейся сборке, поэтому, если атрибут не определен в этой сборке, он не будет настроен должным образом?   -  person Tim Lloyd    schedule 22.06.2011
comment
Да, может быть - это может быть связано с ответом Эбена ниже   -  person Matt Roberts    schedule 22.06.2011


Ответы (2)


Подводя итог сказанному Бибху. Все это связано с log4net.Config.XmlConfigurator.

Вы должны настроить log4net до начала регистрации. Поэтому всякий раз, когда вы используете свой класс LogManager, хостинговое приложение (Windows, Интернет) должно настраивать ведение журнала.

Либо так, либо вам нужно сделать это в вашем LogManager.

person Eben Roux    schedule 22.06.2011
comment
Поэтому, если используется класс LogManager И этот класс находится в другой сборке, мне нужно вручную вызвать XmlConfigurator.Configure () в моем global.asax.cs. Это исправляет, но я не понимаю - почему это будет работать, если я настрою свой _logger на нормальный способ? - person Matt Roberts; 22.06.2011
comment
ах! согласно комментарию chibacity, я, возможно, пропустил это --- где определен бит [assembly: log4net.Config.XmlConfigurator ...]? Дело в том, что хостинговое приложение должно настраивать log4net (как бы то ни было) - person Eben Roux; 22.06.2011
comment
Правильно - вот в чём проблема! Поскольку я переместил LogManager в другую сборку, у которой нет атрибута сборки, он не работает! Все это имеет смысл сейчас. - person Matt Roberts; 22.06.2011

Сообщите приложению, что нужно настроить log4net с помощью внешнего файла конфигурации. Для этого есть два места. Во-первых, файл global.asax, а во-вторых, файл assemblyInfo.cs. Обратите внимание, что в большинстве случаев вы будете начинать с файла global.asax со всем встроенным кодом. По какой-то причине единственный способ заставить это работать - это сломать global.asax, чтобы использовать код программной части, а затем использовать файл assemblyInfo.cs. В итоге это выглядит так.

global.asax:

<%@ Application Language="C#" Inherits="GlobalAsax" %>

global.asax.cs (in your App_Code folder):

using System;
using System.Web;

public class GlobalAsax : HttpApplication
{
    // you may have lots of other code here
    void Application_Start(object sender, EventArgs e)
    {
        log4net.Config.XmlConfigurator.Configure();
    }
}

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

AssemblyInfo.cs (in your App_Code folder):

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]

Флаг наблюдения указывает log4net следить за файлом конфигурации на предмет возможных изменений. Это полезно, если вы хотите изменить конфигурацию с регистрации всего до ошибок только в середине тестирования.

Затем начните регистрацию.

person Bibhu    schedule 22.06.2011
comment
Не совсем уверен, почему вы дали мне использовать конфигурацию Udp, но я думаю, что ваша главная мысль - это вызываемый метод .Configure (). Но у меня создалось впечатление, что атрибут Assebly устраняет необходимость в этом? - person Matt Roberts; 22.06.2011
comment
@Matt Roberts - Взгляните на этот вопрос, он может вам помочь. stackoverflow.com/questions/1731513/ - person Bibhu; 22.06.2011
comment
Спасибо, но это лучший способ. То, что я делаю, работало на меня, и я был доволен этим, но перенос кода в LogManager сработал :) - person Matt Roberts; 22.06.2011
comment
@Matt Roberts - Ваш код должен работать. Можете ли вы перепроверить файл log4net.config. logging.apache.org/log4net - person Bibhu; 22.06.2011
comment
Спасибо за ваши усилия, но ваш последний ответ немного неверен. Если вы используете атрибут сборки для подключения файла конфигурации, вам также не нужно подключать его в Global.asax.cs. Вместо этого вы можете просто вызвать XmlConfigurator.Configure (); - person Matt Roberts; 22.06.2011