Scheduling Reports

Andrew (22 posts)
March 26, 2018 11:59 AM
Accepted Answer

Hi,

Is there a way to schedule the execution and distribution of the adTempus reports?

As part of our release management process, we'd like to have the Object Change Log Report sent to a group of people every Monday morning.

 

Thanks,
Andy

Bill Staff (604 posts)
March 26, 2018 04:45 PM
Accepted Answer
Unfortunately this isn't possible now. We do have it on the enhancement list for version 5.
Andrew (22 posts)
March 28, 2018 07:07 AM
Accepted Answer

Thanks, Bill.

I'll probably implement this in SSRS until version 5 is out.

Bill Staff (604 posts)
April 2, 2018 10:16 AM
Accepted Answer

Getting the data directly from the database is possible but probably a little cumbersome. The descriptions of the objects aren't stored, so you would have to take the OID from each record, join to the correct table, and work out the name/description for each object.

You do this easily through the API using the QueryChangeLog method, which returns a collection of ObjectChangeLog objects.

Here's a quick example that gets all changes for the past 7 days.


void QueryChangeLog(string serverName)
{
	using (var session = Scheduler.Connect(ServerName, LoginAuthenticationType.Windows, "", ""))
	{
		var parms=new ChangeLogQueryParameters();
		parms.ExcludeSystemGenerated=true;	//don't include changes made by the system, e.g., jobs held by job control action
		parms.IncludeObjectDescriptions=true;	//resolve the objects and populate the ObjectDescription field. Otherwise it will be empty.
		parms.AuditOnly=true;	//only get audit records, not snapshot-only records 
		
		parms.EndTimestamp=DateTime.UtcNow;
		parms.StartTimestamp=parms.EndTimestamp.Value.Subtract(TimeSpan.FromDays(7));

		var records = session.QueryChangeLog(parms);
		foreach (var record in records)
		{
			if (record.ChangeType == ObjectChangeType.Delete)
			{
				Console.WriteLine(record.ChangeType + ": " + record.TargetClassName + ": " + record.DeletedObjectDescription);
			}
			else
			{
				Console.WriteLine(record.ChangeType + ": " + record.TargetClassName + ": " + record.ObjectDescription);
			}
		}
	}
}
Andrew (22 posts)
April 4, 2018 07:13 AM
Accepted Answer

This worked great. It's exactly what I needed.

I don't have the ExcludeSystemGenerated property of the ChangeLogQueryParameters object. Is that a new property? I'm using version 4.3.1.1 of the ArcanaDevelopment.adTempus.Shared class.

Bill Staff (604 posts)
April 4, 2018 08:02 AM
Accepted Answer

Yes, it got added later. Without that you may get a lot of change records you don't want. For example, if a Job Control Action modifies a job (by putting it on hold or setting a variable, for example), an audit record will get generated.

To skip these In your code, you can ignore records where record.SecurityLogin is null.


Andrew (22 posts)
April 4, 2018 09:00 AM
Accepted Answer
This is great. Thank you for the help on this.
Andrew (22 posts)
April 12, 2018 07:56 AM
Accepted Answer

It looks like SecurityLogin is populated with the System account on system changes so here's what I ended up with in case it helps anyone else. I'm returning my own object so I'm not dependent on the adTempus object model.

public IEnumerable<ChangeLogItem> GetObjectChangeLogItems(DateTime startDate, DateTime endDate)
        {
            List<ChangeLogItem> items = new List<ChangeLogItem>();
 
            using (Scheduler conn = Scheduler.Connect(_connectorDescriptor, LoginAuthenticationType.Windows, _adTempusLogin, _adTempusPassword))
            {
                var parms = new ChangeLogQueryParameters();
                parms.IncludeObjectDescriptions = true; //resolve the objects and populate the ObjectDescription field. Otherwise it will be empty.
                parms.AuditOnly = true; //only get audit records, not snapshot-only records
 
                parms.StartTimestamp = startDate;
                parms.EndTimestamp = endDate.AddDays(1); //end date is exclusive so add one day to make it inclusive
 
                var records = conn.QueryChangeLog(parms);
                foreach (var record in records)
                {
                    if ((record.SecurityLogin != null) && (!record.SecurityLogin.ToString().ToLowerInvariant().Equals("system"))) //don't include changes made by the system, e.g., jobs held by job control action
                    {
                        ChangeLogItem item = new ChangeLogItem();
                        item.ChangeType = record.ChangeTypeDescription;
                        item.Comments = record.Comments;
                        item.IsDelete = (record.ChangeType == ObjectChangeType.Delete) ? true : false;
                        item.IsNew = (record.ChangeType == ObjectChangeType.Add) ? true : false;
                        item.IsModified = (record.ChangeType == ObjectChangeType.Modify) ? true : false;
                        item.ObjectName = (item.IsDelete) ? record.DeletedObjectDescription : record.ObjectDescription;
                        item.ObjectType = record.TargetClassName;
                        item.TimeStamp = record.Timestamp.DateTime;
                        item.UserAccount = record.SecurityLogin.ToString();
 
                        items.Add(item);
                    }
                }
            }
 
            return (IEnumerable<ChangeLogItem>)items;
        }

Replies are disabled for this topic.