Почему я получаю пустой журнал событий, когда я делаю это с log4net? - PullRequest
3 голосов
/ 12 августа 2010

У меня есть класс

namespace LogToolsTest
{
    public class Foo
    {
        private static readonly ILog logger = LogManager.GetLogger(typeof(Foo));

        public Foo()
        {

            logger.Debug("Save this text");
            logger.Info("Save this text");
            logger.Warn("Save this text");
            logger.Error("Save this text");
            logger.Fatal("Save this text");


            var b1 = logger.IsDebugEnabled;
            var b2 = logger.IsInfoEnabled;
            var b3 = logger.IsWarnEnabled;
            var b4 = logger.IsErrorEnabled;
            var b5 = logger.IsFatalEnabled;
        }
    }
}

Я проверяю это просто:

 Foo foo = new Foo();

и log4net.config

<?xml version="1.0" encoding="utf-8" ?>
<log4net>
  <root>
    <level value="DEBUG" />
    <appender-ref ref="EventLogAppender" />
  </root>

  <appender name="EventLogAppender" type="log4net.Appender.EventLogAppender" >
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    </layout>
  </appender>


</log4net>

Я добавил в свою сборку информацию:

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

После выполнения этого кода запись в журнале событий отсутствует. Почему это?

Теперь это работает почти нормально: Я удалил log4net.config и изменил свой app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <log4net>
  <root>
    <priority value="ALL" />
    <appender-ref ref="TraceAppender" />
    <appender-ref ref="ConsoleAppender" />
    <appender-ref ref="FileAppender" />
    <appender-ref ref="EventLogAppender" />
  </root>

  <appender name="TraceAppender" type="log4net.Appender.TraceAppender">
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    </layout>
  </appender>

  <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    </layout>
  </appender>

  <appender name="FileAppender" type="log4net.Appender.FileAppender">
    <file value="c:\\LOGS\\SampleLog.txt" />
    <appendToFile value="true" />
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    </layout>
  </appender>
  <appender name="EventLogAppender" type="log4net.Appender.EventLogAppender" >
    <layout type="log4net.Layout.PatternLayout">
    </layout>
  </appender>
</log4net>
<configSections>
  <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>

</configuration>

Но что-то не так. Я вижу в выводе:

System.Configuration.ConfigurationErrorsException: Configuration system failed to initialize ---> System.Configuration.ConfigurationErrorsException: Unrecognized configuration section log4net. (C:\toolkit\trunk\LogToolsTest\bin\Debug\LogToolsTest.vshost.exe.config line 3)
   at System.Configuration.ConfigurationSchemaErrors.ThrowIfErrors(Boolean ignoreLocal)
   at System.Configuration.BaseConfigurationRecord.ThrowIfParseErrors(ConfigurationSchemaErrors schemaErrors)
   at System.Configuration.BaseConfigurationRecord.ThrowIfInitErrors()
   at System.Configuration.ClientConfigurationSystem.EnsureInit(String configKey)
   --- End of inner exception stack trace ---
   at System.Configuration.ConfigurationManager.PrepareConfigSystem()
   at System.Configuration.ConfigurationManager.GetSection(String sectionName)
   at System.Configuration.PrivilegedConfigurationManager.GetSection(String sectionName)
   at System.Diagnostics.DiagnosticsConfiguration.GetConfigSection()
   at System.Diagnostics.DiagnosticsConfiguration.Initialize()
   at System.Diagnostics.DiagnosticsConfiguration.get_IndentSize()
   at System.Diagnostics.TraceInternal.InitializeSettings()
   at System.Diagnostics.TraceInternal.WriteLine(String message)
   at System.Diagnostics.Trace.WriteLine(String message)
   at log4net.Util.LogLog.EmitErrorLine(String message)
log4net:ERROR DefaultRepositorySelector: Exception while reading ConfigurationSettings. Check your .config file is well formed XML.
System.Configuration.ConfigurationErrorsException: Configuration system failed to initialize ---> System.Configuration.ConfigurationErrorsException: Unrecognized configuration section log4net. (C:\toolkit\trunk\LogToolsTest\bin\Debug\LogToolsTest.vshost.exe.config line 3)
   at System.Configuration.ConfigurationSchemaErrors.ThrowIfErrors(Boolean ignoreLocal)
   at System.Configuration.BaseConfigurationRecord.ThrowIfParseErrors(ConfigurationSchemaErrors schemaErrors)
   at System.Configuration.BaseConfigurationRecord.ThrowIfInitErrors()
   at System.Configuration.ClientConfigurationSystem.EnsureInit(String configKey)
   --- End of inner exception stack trace ---
   at System.Configuration.ConfigurationManager.PrepareConfigSystem()
   at System.Configuration.ConfigurationManager.GetSection(String sectionName)
   at System.Configuration.ConfigurationManager.get_AppSettings()
   at log4net.Util.SystemInfo.GetAppSetting(String key)

foreach appender.

Ответы [ 4 ]

3 голосов
/ 12 августа 2010

Я предполагаю, что у вас есть консольная программа (похоже, вы тестируете log4net).Поэтому первое, что я хотел бы сделать, - убедиться, что ведение журнала работает с более базовыми приложениями.Настройте ConsoleAppender и убедитесь, что вы видите операторы журнала.В этом нет особой необходимости, но, как я уже сказал, я бы так и сделал.

Более важным является включение внутренней отладки , которая должна указывать, почему ничего не записывается в журнал событий.

Скорее всего, у вас есть разрешениепроблема.Срlog4net faq .

2 голосов
/ 12 августа 2010

У вас проблемы с разрешением. Я только что взял ваш код и с одним небольшим изменением добавил источник, который, как я знаю, у моего пользователя есть доступ для записи (MSSQLSERVER)

<appender name="EventLogAppender" type="log4net.Appender.EventLogAppender">
   <param name="ApplicationName" value="MSSQLSERVER" />

Запустил вашу программу, и она работала нормально. Вам необходимо настроить все источники , которые вы собираетесь использовать. Когда вы закончите, вам нужно будет перезагрузить компьютер ...

Мой намек на то, что что-то не так, была строка, которая гласила

log4net: EventLogAppender: источник [TestApplication.vshost.exe] зарегистрирован в журнале []

Затем я изменил его на "MSSQLSERVER"

log4net: EventLogAppender: источник [MSSQLSERVER] зарегистрирован в журнале [Приложение]

Некоторые полезные советы по включению отладки:

 <log4net debug="true">

Или создайте app.config со следующими настройками:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="log4net.Internal.Debug" value="true" />
  </appSettings>
  <system.diagnostics>
    <trace autoflush="true">
      <listeners>
        <add
            name="textWriterTraceListener"
            type="System.Diagnostics.TextWriterTraceListener"
            initializeData="trace.txt" />
      </listeners>
    </trace>
  </system.diagnostics>

</configuration>
0 голосов
/ 12 августа 2010

Одна вещь, которую я не упомянул, это то, копирует ли файл Log4Net.config в ваш каталог bin. Я сталкивался с этим несколько раз, и это легко исправить.

В обозревателе решений щелкните правой кнопкой мыши файл Log4Net.config и убедитесь, что для поля Copy to Output Directory установлено значение Copy Always или Copy if Newer (по вашему выбору). Я склонен упускать этот шаг при первоначальной настройке решения.

Надеюсь, это поможет вам.

0 голосов
/ 12 августа 2010

Вам не нужно вызывать XmlConfigurator.Configure () из-за строки, которую вы вводите в свой assemblyinfo.Однако, если у вас есть куча сборок, важно помнить, что ПЕРВЫЙ проект, содержащий вызов журнала, - это тот, чья ассемблерная информация нуждается в этой строке.

Другими словами, если у вас естьпроект командной строки и проект dll, и проект командной строки выполняет новый Foo (), но Foo определен в проекте dll, это проект dll, которому нужна строка в его информации о сборке.Но если вы затем добавите вызов журнала в проект командной строки с надписью «Я собираюсь позвонить Foo», ваше ведение журнала перестанет работать (потому что теперь консольный проект является первым, который выполняет вызов журнала, и в строке конфигурации требуетсячтобы быть в этой информации о сборке!).

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...