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>
Может быть, там есть что-то, что помогает