次のシナリオがあります。
- 自己ホスト型 Quartz スケジューラ サービスを実行する Windows サービス。
- Quartz Scheduler Service によってトリガーされたときに実行される「ジョブ」である多くのクラスを含むクラス ライブラリがあります。
- そのジョブのアクティビティを特定のフォルダーとファイルに記録するように、各「ジョブ」クラスで NLog を構成しました。これにより、各「ジョブ」のすべてのログを論理的に分離でき、xml 構成ファイルを使用して実行時に個々の「ジョブ」のログをオンまたはオフにすることができます。
- 起動情報をスケジューラ ログに記録するように Quartz スケジューラを設定しました。
これはすべて問題なく動作しています。
ここでやりたいことは、Quartz Scheduler のデフォルトの情報出力を別の別の NLog ログに記録することですが、Quartz で使用される一般的なログ フレームワークから、これを NLog に「パイプ」する方法がわかりません。ロギング構成はすべてプログラムによって行われるため、実行時に個々の「ジョブ」ログごとにロギングのオンとオフを切り替えることができます。
これが私のNLog構成の縮小版です-
?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true">
<targets async="True" xsi:type="AsyncWrapper" queueLimit="20000">
<!--Scheduler Logging Section-->
<target name="sInfo" xsi:type="File"
fileName="${basedir}/logs/Scheduler/SchedulerInfolog.txt"
layout="[${date:format=dd-MM-yyy HH\:mm\:ss}] ${message}"
keepFileOpen="false"
archiveFileName="${basedir}/logs/archive/Scheduler/SchedulerInfoLog{#}.txt"
archiveEvery="Month"
archiveNumbering="Rolling"
maxArchiveFiles="10"
archiveAboveSize="10485760"/>
</targets>
<rules>
</rules>
</nlog>
これをスケジューラクラスで宣言しましたが、
Private Shared Logger As NLog.Logger = LogManager.GetLogger("Scheduler")
Private xlc As LoggingConfiguration = LogManager.Configuration
Private sInfoRule As New LoggingRule
Private sTraceRule As New LoggingRule
Private sErrorRule As New LoggingRule
Private sfileTarget As New FileTarget
Quartz Scheduler の起動プロセスで、このコードを実行するメソッドを呼び出します。
If infoEnabled Then
sInfoRule = New LoggingRule("Scheduler", LogLevel.Info, xlc.FindTargetByName("sInfo"))
xlc.LoggingRules.Add(sInfoRule)
sInfoRule.DisableLoggingForLevel(LogLevel.Fatal)
sInfoRule.DisableLoggingForLevel(LogLevel.Error)
sInfoRule.DisableLoggingForLevel(LogLevel.Warn)
End If
LogManager.Configuration = xlc
LogManager.ReconfigExistingLoggers()
このようにQuartz Schedulerを設定していますが、
Dim properties = New NameValueCollection()
properties("quartz.scheduler.instanceName") = "SRCTaskScheduler"
properties("quartz.threadPool.type") = "Quartz.Simpl.SimpleThreadPool, Quartz"
properties("quartz.threadPool.threadCount") = "20"
properties("quartz.threadPool.threadPriority")
= "Normal"
properties("quartz.plugin.jobInitializer.type") = "Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin, Quartz"
properties("quartz.plugin.jobInitializer.fileNames") = path & "ScheduledTasks.xml"
properties("quartz.plugin.jobInitializer.failOnFileNotFound")
= "true"
properties("quartz.plugin.jobInitializer.scanInterval") = "60"
properties("quartz.plugin.triggerHistory.type") = "Quartz.Plugin.History.LoggingTriggerHistoryPlugin, Quartz"
properties("quartz.plugin.triggerHistory.triggerFiredMessage") = "Trigger
[{1}.{0}] fired job [{6}.{5}] scheduled at: [{2:dd/MM/yyyy HH:mm:ss]}, next scheduled at: [{3:dd/MM/yyyy HH:mm:ss}]"
properties("quartz.plugin.triggerHistory.triggerCompleteMessage") = "Trigger [{1}.{0}] completed firing job [{6}.{5}] with resulting trigger
instruction code: {9}. Next scheduled at: {3:dd/MM/yyyy HH:mm:ss}"
properties("quartz.plugin.triggerHistory.triggerMisfiredMessage") = "Trigger [{1}.{0}] misfired job [{6}.{5}]. Should have fired at: {3:dd/MM/yyyy HH:mm:ss}"
properties("quartz.plugin.jobHistory.type")
= "Quartz.Plugin.History.LoggingJobHistoryPlugin, Quartz"
properties("quartz.plugin.jobHistory.jobToBeFiredMessage") = "Job [{1}.{0}] to be fired by trigger [{4}.{3}] at: [{5:dd/MM/yyyy HH:mm:ss}] with re-fire: {7}"
properties("quartz.plugin.jobHistory.jobSuccessMessage")
= "Job [{1}.{0}] execution complete, next Schedule at: [{6:dd/MM/yyyy HH:mm:ss}] and reports: [{8}] "
properties("quartz.plugin.jobHistory.jobFailedMessage") = "Job [{1}.{0}] execution failed with exception: [{8}]"
properties("quartz.plugin.jobHistory.jobWasVetoedMessage")
= "Job [{1}.{0}] was vetoed. It was to be fired by trigger [{4}.{3}] at: [{2:dd-MM-yyyy HH:mm:ss.SSS}]"
properties("quartz.plugin.ShutdownHook.type") = "Quartz.Plugin.Management.ShutdownHookPlugin, Quartz"
properties("quartz.plugin.ShutdownHook.CleanShutdown")
= "false"
Dim sf As ISchedulerFactory = New StdSchedulerFactory(properties)
_scheduler = sf.GetScheduler()
次に、その特定のログ ファイルに次のように書き込むことができます。
Logger.Trace("[Scheduler configuration has completed.]")
Logger.Info("[Starting Scheduler System.]")
これは奇妙に思えるかもしれませんが、このすべての背後にある理由は、ジョブが完了すると、そのジョブの次のトリガー時刻をその特定のジョブ ログに書き込みますが、スケジューラーでトリガー時刻を変更すると、その記録がどこにもないためです。変更すると、そのジョブのトリガーが時間どおりに起動されなかったように見えます-理想的には、Quartz Scheduler の出力を新しいスケジュールで読み取ったときにログに記録したいのですが、それは飛躍しすぎていると思います.
私の計画 B、これが不可能な場合は、ジョブを 60 秒ごとに実行するように構成し、現在のスケジューラ設定をログに記録することです。プランAを機能させることが可能である場合、私にはその仕事を完了するための知識とスキルがありません.