Quartz.Net, ведение журнала с помощью Log4Net и Common.Logging выдает "неизвестный уровень журнала"

У меня есть облачный сервис Azure, который использует Quartz.Net (2.3.2) для выполнения запланированных задач. Мой основной механизм ведения журналов - это Log4Net (2.0.3), и я использую Common.Logging.Log4Net1213 (3.0.0) для соединения Common.Logging и Log4Net. Я использую свой собственный "NinjectJobFactory" для создания всех заданий и их зависимостей (он реализует IJobFactory). Мой код запуска расписания выглядит так:

  _scheduler = factory.GetScheduler();
  _scheduler.JobFactory = new NinjectJobFactory(_kernel);
  _scheduler.Start();

Все отлично работает для обычной ежедневной регистрации (запуск и выключение Quartz, запуск NServiceBus, запуск задач, обработка исключений внутри заданий и т. Д.). Проблема в том, что в любой из приведенных выше строк есть фатальное исключение, которое препятствует запуску Quartz. (Обычно это происходит из-за того, что мне не удалось правильно включить или настроить зависимость, которая требуется для одного из заданий). При этих обстоятельствах вместо регистрации реальной проблемы я получаю исключение внутри Log4NetLogger.cs с жалобой на неизвестный уровень ведения журнала, и основное исключение никогда не обнаруживается и не регистрируется. Я должен разбить на пойманные исключения, чтобы увидеть основное исключение. Кто-нибудь может предложить исправить? Заранее спасибо!

Трассировка стека выглядит следующим образом:

Microsoft.WindowsAzure.ServiceRuntime Критическое состояние: 1: необработанное исключение: System.ArgumentOutOfRangeException: неизвестный уровень журнала Имя параметра: logLevel Фактическим значением было Ошибка. в Common.Logging.Log4Net.Log4NetLogger.GetLevel(LogLevel logLevel) в c:_oss\common-logging\src\Common.Logging.Log4Net129\Logging\Log4Net\Log4NetLogger.cs: строка 180 в Common.Logging.Log4Net.Log4.WriteInternal(LogLevel logLevel, сообщение объекта, исключительная ситуация) в c:_oss\common-logging\src\Common.Logging.Log4Net129\Logging\Log4Net\Log4NetLogger.cs: строка 140 в Common.Logging.Factory.AbstractLogger.Error(Object сообщение, исключение) в c:_oss\common-logging\src\Common.Logging.Portable\Logging\Factory\AbstractLogger.cs: строка 806 в Quartz.Simpl.SimpleThreadPool.WorkerThread.Run() в c:\Program Files (x86)\Jenkins\workspace\Quartz.NET\src\Quartz\Simpl\SimpleThreadPool.cs: строка 492 в System.Threading.ExecutionContext.RunInternal(ExecutionContext executeContext, обратный вызов ContextCallback, состояние объекта, логическое preserveSyncCtx) в System.Threading.ExecutionContext.Run(ExecutionContext executeContext, обратный вызов ContextCallback, состояние объекта, логическое preserveSyncCtx) в Sy stem.Threading.ExecutionContext.Run (ExecutionContext executeContext, обратный вызов ContextCallback, состояние объекта) в System.Threading.ThreadHelper.ThreadStart()

Моя конфигурация common.logging в app.config:

<common>
    <logging>
      <factoryAdapter type="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4Net1213">
        <arg key="configType" value="FILE" />
        <arg key="configFile" value="log4net.config" />
      </factoryAdapter>
    </logging>
  </common>

Наконец, мой log4net.config:

<log4net>
  <appender name="ErrorAppender" type="log4net.Appender.BufferingForwardingAppender">
    <bufferSize value="1" />
    <lossy value="true" />
    <evaluator type="log4net.Core.LevelEvaluator">
      <threshold value="INFO" />
    </evaluator>
    <appender-ref ref="TraceAppender" />
  </appender>
  <appender name="TraceAppender" type="log4net.Appender.TraceAppender">
    <threshold value="INFO" />
    <filter type="log4net.Filter.LoggerMatchFilter">
      <loggerToMatch value="NServiceBus.Azure.Transports.WindowsAzureServiceBus.AzureServiceBusQueueCreator" />
      <acceptOnMatch value="false" />
    </filter>
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%message%newline" />
    </layout>
  </appender>
  <root>
    <level value="ALL" />
    <appender-ref ref="ErrorAppender" />
  </root>
</log4net>

2 ответа

Это может показаться глупым, но я столкнулся с точно такой же проблемой, и я преодолел ее, убедившись, что версии common.logging, common.logging.core и common.logging.log4net1213 были одной и той же версии (3.3.1), По-видимому, между тремя библиотеками существует зависимость от версии, и если одна используется с другой, не той же версией, это может привести к.

Вот декомпилированный код для функции, из которой исходит ваше исключение. Оно произошло от Common.Logging.Log4Net1213 v3.3.1, Предыдущие версии этого кода не учитывали Common.Logging.LogLevel.Warnи поэтому исключение выпало в нижней части оператора switch:

 public static Level GetLevel(Common.Logging.LogLevel logLevel)
    {
      switch (logLevel)
      {
        case Common.Logging.LogLevel.All:
          return Level.All;
        case Common.Logging.LogLevel.Trace:
          return Level.Trace;
        case Common.Logging.LogLevel.Debug:
          return Level.Debug;
        case Common.Logging.LogLevel.Info:
          return Level.Info;
        case Common.Logging.LogLevel.Warn:
          return Level.Warn;
        case Common.Logging.LogLevel.Error:
          return Level.Error;
        case Common.Logging.LogLevel.Fatal:
          return Level.Fatal;
        default:
          throw new ArgumentOutOfRangeException("logLevel", (object) logLevel, "unknown log level");
      }
    }

В моем случае common.logging.log4net1213 был одной версией других (v3.3.0), поэтому я обновил библиотеку до той же версии, что и две другие библиотеки, и проблема исчезла.

Удачи!

Можете ли вы показать нам свой лог конфигурации?

Моя реализация Servicebus/log4net/quartz успешно регистрирует проблемы с запуском кварца. Это код запуска, который я использую; не уверен, поможет ли это, так как не виден твой код.

NSB Версия 4.6.2

public class MyServer : ServiceControl
{
    private readonly ILog logger;
    private ISchedulerFactory schedulerFactory;
    private IScheduler scheduler;

    public static IBus Bus = null;

    public MyServer()
    {
        logger = LogManager.GetLogger(GetType());                       
    }


    public virtual void Initialize()
    {
        try
        {                           
            log4net.GlobalContext.Properties["Job"] = "Quartz";

            Configure.Serialization.Xml();
            Configure.Transactions.Enable();
            SetLoggingLibrary.Log4Net();

            Bus = Configure.With().DefaultBuilder().UnicastBus().SendOnly();

            schedulerFactory = CreateSchedulerFactory();
            scheduler = GetScheduler();
        }
        catch (Exception e)
        {
            logger.Error("Server initialization failed:" + e.Message, e);
            throw;
        }
    } 
}

public class Configuration
{
    private static readonly NameValueCollection configuration;

    static Configuration()
    {
        configuration = (NameValueCollection)ConfigurationManager.GetSection("quartz");
    }


    static public string GetQuartzConfigFileName()
    {
        return configuration["quartz.plugin.xml.fileNames"] as String;
    }
}

И мой конфиг приложения выглядит так

<configuration>
  <configSections>
    <section name="quartz" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
    <sectionGroup name="common">
      <section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
    </sectionGroup>
    </configSections>
  <common>
   <logging>
      <factoryAdapter type="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4net1211">
        <arg key="configType" value="INLINE" />
      </factoryAdapter>
    </logging>
  </common>
  <log4net debug="false">
    <appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
      <mapping>
        <level value="FATAL" />
        <foreColor value="Red, HighIntensity" />
      </mapping>
      <mapping>
        <level value="ERROR" />
        <foreColor value="Red, HighIntensity" />
      </mapping>
      <mapping>
        <level value="WARN" />
        <foreColor value="Yellow" />
      </mapping>
      <mapping>
        <level value="INFO" />
        <foreColor value="Green" />
      </mapping>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
      </layout>
    </appender>

    <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
      <file value="GrafOI.Scheduler.log" />
      <appendToFile value="true" />
      <rollingStyle value="Size" />
      <maxSizeRollBackups value="10" />
      <maximumFileSize value="10000KB" />
      <staticLogFileName value="true" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
      </layout>
    </appender>

    <!-- quartz clutters the logs so turn it off unless an error occurs -->
    <logger name="Quartz">
      <level value="ERROR" />
    </logger>

    <root>
      <level value="DEBUG" />
      <appender-ref ref="AdoNetAppender" />
      <appender-ref ref="EventLogAppender" />
      <appender-ref ref="ColoredConsoleAppender" />
      <appender-ref ref="RollingFileAppender" />
    </root>
  </log4net>
  <quartz>
    <add key="quartz.scheduler.instanceName" value="GrafOI Scheduler" />
    <add key="quartz.threadPool.type" value="Quartz.Simpl.SimpleThreadPool, Quartz" />
    <add key="quartz.threadPool.threadCount" value="2" />
    <add key="quartz.threadPool.threadPriority" value="Normal" />
    <add key="quartz.jobStore.misfireThreshold" value="60000" />
    <add key="quartz.jobStore.type" value="Quartz.Impl.AdoJobStore.JobStoreTX, Quartz" />
    <add key="quartz.jobStore.driverDelegateType" value="Quartz.Impl.AdoJobStore.StdAdoDelegate, Quartz" />
    <add key="quartz.jobStore.tablePrefix" value="QRTZ_" />
    <add key="quartz.jobStore.dataSource" value="myDS" />
    <add key="quartz.dataSource.myDS.connectionString" value="server=.;database=GrafOI;Integrated Security=true;" />
    <add key="quartz.dataSource.myDS.provider" value="SqlServer-20" />
    <add key="quartz.plugin.xml.type" value="Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin, Quartz" />
    <add key="quartz.plugin.xml.fileNames" value="~/GrafOI.Scheduler.Jobs.xml" />
    <add key="quartz.jobStore.useProperties" value="true" />

  </quartz>
  <appSettings>

  </appSettings>

</configuration>

Может быть, там есть что-то, что помогает

Другие вопросы по тегам