开发者

How to maintain a job history using Quartz scheduler

I'd like to maintain a history of jobs that were scheduled by a Quartz scheduler containing the following properties: 'start time', 'end time', 'success', 'error'.

There are two interfaces available for this: ITriggerListener and IJobListener (I'm using the C# naming convention for interfaces because I'm using Quartz.NET but the same question could be asked for the Java version).

IJobListener has a JobToBeExecuted and a JobWasExecuted method. The latter provides a JobExecutionException so that you know when something went wrong. However, there is no way to correlate JobToBeExecuted and JobWasExecuted. Suppose my job runs for ten minutes. I start it at t0 and t0+2 (so they overlap). I get two calls to JobToBeExecuted and insert two start times into my history table. When both jobs finish at t1 and t1+2 I get two calls to JobWasExecuted. How do I know what database record to update in each call开发者_StackOverflow社区 (to store an end time with its corresponding start time)?

ITriggerListener has another problem. There is no way to get any errors inside the TriggerComplete method when a job failed.

How do I get the desired behavior?


The way to do this is to generate an identifier in JobToBeExecuted, store it in the JobExecutionContext and retrieve it again from the JobExecutionContext in JobWasExecuted.

public void JobToBeExecuted(JobExecutionContext context)
{
    // Insert history record and retrieve primary key of inserted record.
    long historyId = InsertHistoryRecord(...);
    context.Put("HistoryIdKey", historyId);
}

public void JobWasExecuted(JobExecutionContext context,
                           JobExecutionException jobException)
{
    // Retrieve history id from context and update history record.
    long historyId = (long) context.Get("HistoryIdKey");
    UpdateHistoryRecord(historyId, ...);
}


The scheduler has to maintain a key that lets it correlate each history entry. There must be a unique job ID of some kind that's created when a job kicks off to be able to accomplish this.

You don't mention such a thing, so I thought it was worth a suggestion.

UPDATE: I'd INSERT a record into the database when a job is created and get back the primary key (maybe a GUID). I'd use that as the key.


If you're happy to just update the database at the end, you can get the job name and run time from the IJobExecutionContext:

public void JobWasExecuted(JobExecutionContext context,
                       JobExecutionException jobException)
{
    var sql = @"INSERT INTO MyJobAuditHistory 
                (JobKey, RunTime, Status, Exception) VALUES (?, ?, ?, ?)";

    // create command etc.
    command.Parameters.Add(context.JobDetail.Key.ToString());
    command.Parameters.Add(context.JobRunTime);
    command.Parameters.Add(jobException == null ? "Success" : "Fail");
    command.Parameters.Add(jobException == null ? null : jobException.Message);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜