How to get date and time of the latest run for a specified task (step)

GuyS (45 posts)
December 15, 2018 03:03 PM
Accepted Answer

Hi Bill,

 

I have a task ('PrepProd'), being a Micro Focus job, defined as a step in a job ('RunProduction') .

I need to know the startdate/time of the latest run of this task in my C# program.

Could you help me with an example of how to get this information please?

 

Thanks very much,

 

Guy

Bill Staff (599 posts)
December 16, 2018 09:15 AM
Accepted Answer

Here's code with two different approaches. The first just looks at the Status object for the job, which reflects the most recent instance. However, if the job is running when you run your program, you'll be looking at the executing instance. To be sure you get the most recent completed instance, use the second approach, which queries the history for the job.

I'm assuming you can just use the start time for the job instance. If you need to get the start time of the step within the job, use the second approach, and then iterate through instance.Steps to find the step you want and get its ExecutionStart.

    DateTimeOffset? lastExecutionStart;
    using (var session = Scheduler.Connect(ServerName, LoginAuthenticationType.Windows, "", ""))
    {
        using (var context = session.NewDataContext())
        {
            var job=context.GetJob("RunProduction");
            
            var status=job.GetStatus(false);
            
            //The Status object has information about the most recent execution.
            //(If the job is currently active, this will be the active instance).
            lastExecutionStart = status.ExecutionStart;
            
            //If the job might be running when you execute this code, you need to query the
            //history instead of looking at the main status, to make sure you're getting 
            //the most recent completed only completed instance.

            var options=new InstanceQueryParameters();
            
            //query history only for the job fetched above
            options.TargetObjects.Add(job.OID);
            
            //only query for instances that have finished
            options.Statuses.AddRange(JobStatusHelpers.FinalStatuses);
            
            //only get one instance
            options.PageSize=1;
            options.PageNumber=1;
            
            //RecordID is assigned sequentially to each instance. Sort descending on this so the most recent
            //instance is returned first
            options.SortOrder.Add( ArcanaDevelopment.adTempus.Shared.InstanceQueryParameters.HistorySortOrder.RecordIDDescending);

            var instances = context.GetJobHistory(options);
            if (instances.Count > 0)
            {
                //this will be the most recent completed instance
                var instance=instances[0];

                lastExecutionStart = instance.ExecutionStart;
            }
        }
    }

GuyS (45 posts)
December 18, 2018 07:57 AM
Accepted Answer

 Hi Bill,

 

I'm glad I asked for an example. It would have cost me some time to get this running. THANKS, again.

I want the date/time of 'RunProduction', not  'PrepProd', but I hope I can find that.

Your example fails when there is no history, but that's a small C# thing.

 

Kind regards,

Guy 

 

 

Bill Staff (599 posts)
December 18, 2018 08:06 AM
Accepted Answer
GuyS wrote:
I want the date/time of 'RunProduction', not 'PrepProd', but I hope I can find that.

My sample is getting the "RunProduction" job. Is that not what you're asking?

GuyS wrote:
Your example fails when there is no history, but that's a small C# thing.

It shouldn't fail. What error are you getting?

GuyS (45 posts)
December 19, 2018 02:20 AM
Accepted Answer

Hi Bill,

 

This is the situation:

When I give "LPS\\LPS18GS\\HouseKeeping\\18 SpoolArchivering" as parameter, I get the date/timestamp:

 

 

This is my adTempus: 

 

Maybe I can you this date, but I would prefer the rundate of "HSKSPOOL".

Aditional info: HSKSPOOL could be used in more then 1 Group :-) 

And to make it more complex, I would like the value of an specified adTempus-variable in that run :-) 

 

 

 
Bill Staff (599 posts)
December 19, 2018 07:16 AM
Accepted Answer

So you have many different jobs with a step named "HSKSPOOL" in them, and you want the most recent execution of a step with that name, whatever job it's in?

GuyS (45 posts)
December 19, 2018 07:52 AM
Accepted Answer

 Hi Bill,

 

No, not that much. The LPS\LPS18GS is a test-region, just like LPS\TST01.

In this case I want de steps within a test-region.

I can have HSKSPOOL in more then 1 job within LPS\LPS18GS but I like to have the last run-date\time for each job.

If I can specify the Job, that would be nice. 

 

Example: 

LPS\LSP18GS\Maand\Run-1: step1 - HSKSPOOL 

                                          step2 - …..

LPS\LSP18GS\Maand\Run-2: step1 - HSKSPOOL 

                                           step2 - …..

 

I could split the jobs to make HSKSPOOL unique, but that's another way (not preferred).

My intention was to use something like: 

 

sName = "HSKSPOOL"; 

jName = "LPS\LPS18GS\Maand\Run-1" 

run1 = GetLastRunDate(jName + @"/" + sName) 

jName = "LPS\LPS18GS\Maand\Run-2" 

run2 = GetLastRunDate(jName + @"/" + sName) 

if (run2 < run1) …… etc. 

 

 

Bill Staff (599 posts)
December 19, 2018 09:17 AM
Accepted Answer

In that case, as I mentioned in my initial reply, you need to look through the steps of the most recent job instance and find the right step.

Update the original code like this (where sName is the name of the step you're looking for):

            if (instances.Count > 0)
            {
                //this will be the most recent completed instance
                var instance = instances[0];
                
                foreach(var step in instance.Steps)
                {
                    if(step.StepDescription.ToLower().Contains(sName.ToLower()))
                    {
                        lastExecutionStart=step.ExecutionStart;    
                    }
                }
            }
Bill Staff (599 posts)
December 19, 2018 09:29 AM
Accepted Answer

You mentioned that you want to get a variable value from the instance as well. Variable values are recorded in the Job Detail Log but you'll have to do a little work to get the value out.

Once you have the instance (either before or after you look for the step; doesn't matter):

                var instance = instances[0];
                foreach (var capturedFile in instance.CapturedFiles)
                {
                    if (capturedFile.OriginalFileName == "Job Detail Log.xml")
                    {
                        var variableValue = ReadVariableValue(capturedFile, "variableName");
                    }
                }

That finds the right captured file entry. Now you have to process the file. Here's the basic approach:

string ReadVariableValue(CapturedFile file,string variableName)
{
    using(var stream=new MemoryStream())
    {
        file.WriteContentsToStream(stream);
        stream.Position=0;
        
        //load the stream contents into an XML doucument and parse it.
        //there will be a message element reporting "begin step" for the step. You'll  need to work 
        //through until you get to the right step based on the step name.
        //Then somewhere after that will be another message element containing a list of
        //variable values at the end of the step. You'll need to find the right message,
        //then parse out the variable value.
    }    
}

Take a look at the file in the Console to see what you're dealing with. You'll need to find the message element reporting the start of the step you want, then continue on to find the message element reporting the variable values at the end of that step. Then read the list of variables and parse out the value you want.

 

Replies are disabled for this topic.