Features, discussions, tips, tricks, questions, problems and feedback

Script to Retrieve Agent Names from AgentGroup

Hello all,

I’m looking for assistance with a script development to monitor specific agents for error states. I’m starting with DBLog agents and need to retrieve all available names from the Datasource.

My goal is to access “Adroit.AgentGroup.DBLog.memberNames” and compile these into a DataElementCollection. I attempted this with the script below, but it’s not returning the expected results.

Any guidance on resolving this would be appreciated!

Thank you in advance.

private void CheckStatus()
        {

            // Retrieve the list of DBLog member names
            MethodReturnInfo infoMembers = MyConnection.ReadDataElement("Adroit.AgentGroup.DBLog.memberNames");
            DataElement dblogMembersElement = infoMembers.ReturnObject as DataElement;

            // Ensure the response is valid and contains the expected array of names
            if (infoMembers.Success)
            {
                //I don't know if this is right.
                string[] dblogMemberNames = dblogMembersElement.Value as string[];

                // Create a collection to hold the specific DataElements we're interested in
                DataElementCollection decdblog = DataElementEngine.NewDataElementCollection();

                // Add ConnectionError and lastError elements for each DBLog member
                foreach (string dblogName in dblogMemberNames)
                {
                    // Define ConnectionError and lastError elements based on each DBLog name
                    DataElement dedblogError = DataElementEngine.NewDataElement("Adroit.DBLog." + dblogName + ".ConnectionError");
                    DataElement dedblogErrorMessage = DataElementEngine.NewDataElement("Adroit.DBLog." + dblogName + ".lastError");

                    decdblog.Add(dedblogError);
                    decdblog.Add(dedblogErrorMessage);
			     }		

               }

       }

Hi Douglas,

A few things to note:

  1. ReadDataElement and ReadDataElements calls always return a DataElementCollection.
  2. Agent list slots i.e. like memberNames read from the AdroitDataSource, return a DataSet with a single DataTable with the results.

I have modified your script as below to show this:

        private void CheckStatus()
    {
        // Retrieve the list of DBLog member names
        MethodReturnInfo infoMembers = MyConnection.ReadDataElement("Adroit.AgentGroup.DBLog.memberNames");

        // Ensure the response is valid and contains the expected array of names
        if (infoMembers.Success)
        {
            // ReadDataElement returns a DataElementCollection
            DataElementCollection returnDec = infoMembers.ReturnObject as DataElementCollection;
            DataElement dblogMembersElement = returnDec["Adroit.AgentGroup.DBLog.memberNames"];

            // All list slots i.e. memberNames, return a DataSet with a single DataTable with the result
            DataSet dblogMembersDS = dblogMembersElement.Value as DataSet;
            DataTable dblogMembersDT = dblogMembersDS.Tables[0];

            // Get the list of dblog membernames from the returned table
            List<string> dblogMemberNames = new List<string>();
            foreach (DataRow row in dblogMembersDT.Rows)
            {
                dblogMemberNames.Add(row[0].ToString());
            }

            // Create a collection to hold the specific DataElements we're interested in
            DataElementCollection decdblog = DataElementEngine.NewDataElementCollection();

            // Add ConnectionError and lastError elements for each DBLog member
            foreach (string dblogName in dblogMemberNames)
            {
                // Define ConnectionError and lastError elements based on each DBLog name
                DataElement dedblogError = DataElementEngine.NewDataElement("Adroit.DBLog." + dblogName + ".ConnectionError");
                DataElement dedblogErrorMessage = DataElementEngine.NewDataElement("Adroit.DBLog." + dblogName + ".lastError");

                decdblog.Add(dedblogError);
                decdblog.Add(dedblogErrorMessage);
            }

            // Read the ConnectionError and lastError elements for each DBLog member
            MethodReturnInfo mri = MyConnection.ReadDataElements(decdblog);
            if (mri.Success)
            {
                returnDec = mri.ReturnObject as DataElementCollection;

                foreach (DataElement dataElement in returnDec.Values)
                {
                    lbDBLogStatus.Items.Add(dataElement.Name + " value is " + dataElement.Value.ToString());
                }
            }

        }

    }

I have also included a sample graphic form below showing this as well:

CheckDBLogStatus.viz (15.3 KB)

Hope this help.

Regards,
Diego

1 Like

Some additional notes when considering scripting:

  1. Scripting provides a lot of flexibility and power, but it requires additional considerations for error handling, performance and memory usage in general.
  2. When considering the use of scripting, first investigate whether there are other built-in options that may solve the problem. For example, In the use-case above consider alarming the error states OR providing logic regarding the error states in an Expression Agent. Both of these options will perform better than a script.
  3. In the script above, it is recommended to wrap the code in a “Try/Catch” block in order to prevent unhandled exceptions:

For example:

try
{
<your code here>
}
catch (Exception ex)
{
//NOTE: This will log an entry to the eventlog if the script is run in an application with admin rights (i.e. Server, Designer). The operator is normally running with lower privileges, so in the Operator an entry will not be written to the EventLog UNLESS it is "Run as Administrator".
VIZNET.Shared.Logging.EventLog.GetInstance().WriteEntry("An error occurred: "+ex.ToString(), EventLogEntryType.Error, 1001);
}
  1. In the script reference above, the call to get the data element list is potentially expensive in terms of memory usage and performance, so it should only be called periodically and not on a regular interval.
1 Like