我有一个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实际值为Error。在 Common.Logging.Log4Net.Log4NetLogger.GetLevel(LogLevel logLevel)in C:_oss \共记录\ SRC \ Common.Logging.Log4Net129 \记录\ log4net的\ Log4NetLogger.cs:线 180.在Common.Logging.Log4Net.Log4NetLogger.WriteInternal(LogLevel logLevel,Object message,Exception exception)in C:_oss \共记录\ SRC \ Common.Logging.Log4Net129 \记录\ log4net的\ Log4NetLogger.cs:线 140.在Common.Logging.Factory.AbstractLogger.Error(对象消息, 例外情况) C:_oss \共记录\ SRC \ Common.Logging.Portable \记录\厂\ AbstractLogger.cs:线 806在Quartz.Simpl.SimpleThreadPool.WorkerThread.Run()中 c:\ Program Files (86)\詹金斯\工作空间\ Quartz.NET \ SRC \石英\ SIMPL \ SimpleThreadPool.cs:线 492在 System.Threading.ExecutionContext.RunInternal(执行上下文 executionContext,ContextCallback回调,对象状态,布尔值 preserveSyncCtx)at System.Threading.ExecutionContext.Run(执行上下文 executionContext,ContextCallback回调,对象状态,布尔值 preserveSyncCtx)at System.Threading.ExecutionContext.Run(执行上下文 executionContext,ContextCallback回调,对象状态)at System.Threading.ThreadHelper.ThreadStart()
app.config中的common.logging配置为:
<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>
答案 0 :(得分:2)
这可能听起来很傻,但我遇到了完全相同的问题,我通过确保common.logging,common.logging.core和common.logging.log4net1213的版本都是相同的版本来克服它(3.3 0.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),因此我将库更新为与其他两个库相同的版本,并且问题已经消失。
祝你好运!答案 1 :(得分: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;
}
}
我的app配置看起来像这样
<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>
也许有些东西可以帮助