1

我有一个 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:Common.Logging.Log4Net.Log4NetLogger 的第 180 行。 WriteInternal(LogLevel logLevel, Object message, Exception exception) in c:_oss\common-logging\src\Common.Logging.Log4Net129\Logging\Log4Net\Log4NetLogger.cs:Common.Logging.Factory.AbstractLogger.Error(Object) 的第 140 行消息,异常异常)在 c:_oss\common-logging\src\Common.Logging.Portable\Logging\Factory\AbstractLogger.cs:c 中 Quartz.Simpl.SimpleThreadPool.WorkerThread.Run() 的第 806 行:

我在 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>
4

2 回答 2

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)的一个版本,因此我将库更新为与其他两个库相同的版本,问题就消失了。

祝你好运!

于 2017-01-11T17:21:54.790 回答
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>

也许那里有一些帮助

于 2015-10-09T09:50:13.717 回答