csawyer

Mass Event Frame Deletion in AF SDK 2.10

Blog Post created by csawyer Employee on Jul 17, 2018

Got a bunch of Event Frames laying around?

 

Getting rid of old event frames in your database is now made much easier in AF SDK 2.10 with the new DeleteEventFrames() method that is hanging off the AFEventFrame class.

 

All you need to do is collect a list of event frame object IDs and pass it in to DeleteEventFrames(). You do this by performing an Event Frame Search.   The EventFrameSearch object supports returning the located event frames by Object ID-only, which you can use to mass delete them.

 

Why might I want to do this?

 

In some shops you might be creating Event Frames at a significant rate that has nothing to do with alarms and notifications but rather as part of an eventing process.  After those event frames run through your natural business process you may no longer have a desire to keep them around.  It would make sense then to setup a deletion schedule (once a week is recommended) to purge irrelevant data.

 

 

Make Sure To Use FindObjectIds() Where You Can

 

 

If you're doing regular mass deletions of objects it is far more efficient to limit your search returns to the AFObject IDs.  Not only does this reduce network traffic but the underlying database retrievals are going against well-indexed columns in the database which will result in fast returns.  By issuing mass deletes in page blocks (see the pageSize constant) you can loop through an unlimited number of event frames to purge until you have none left.  If your AFDatabase happens to undergo lots of writes and your batch deletes need  to happen when the server is busy, you can reduce the page size and introduce waits between each batch delete block to reduce the time the amount of locking in the underlying SQL database.

 

Observe:

using System;
using System.Linq;
using System.Collections.Generic;
using OSIsoft.AF;
using OSIsoft.AF.EventFrame;
using OSIsoft.AF.Search;

namespace MassEFDelete
{
    class Program
    {
        static void Main(string[] args)
        {

            const int pageSize = 200000;

            PISystems pi = new PISystems();
            PISystem sys = pi.DefaultPISystem;
            AFDatabase db = sys.Databases["Chris"];

            var cpu = db.Elements["CHRISMACAIR"];
            var machinetemplate = db.ElementTemplates["Macs"];

            string query = string.Format("Element:CHRISMACAIR");  // Every event frame where this AFElement is a factor
            var search = new AFEventFrameSearch(db, "CPU Search", query);

            //Use this if you really need to look in the event frames before deleting them,
            //else use the much faster FindObjectIds() method
            //var frames = search.FindEventFrames();  // Get every event

            List<Guid> ids = null;
            while ((ids = search.FindObjectIds(pageSize: pageSize).Take(pageSize).ToList()).Count > 0)
            {
                Console.WriteLine($"Deleting a batch of {ids} Event Frames..");
                AFEventFrame.DeleteEventFrames(sys, ids);
            }

            Console.WriteLine("Completed.");

        }
    }
}

 

Many of you have been frustrated with clearing event frames out in batch. Now you can conduct a lightweight search (fullload=false), grab the IDs out of the search and feed them into bulk delete all at once

Outcomes