OpsMgr from SOA to .NET

Monitoring of Web applications, .NET applications and Service oriented architectures(SOA)

Bulk editing monitor Alert settings and adding descriptions for Web applications

Bulk editing monitor Alert settings and adding descriptions for Web applications

  • Comments 3
  • Likes

It has been a while since I posted to the blog. The long break gave me a chance to work on some of the requests I had received to my previous posting. The posting referred to creating alert descriptions for Web application monitors.

 

Many people wrote to me that this was a fine solution, but how can you change these settings for each monitor and its alert when you have possibly hundreds of Alerts to update. This can be very cumbersome if using the approach suggested in the blog, by updating the settings using the Console.

The OpsMgr SDK provides some handy APIs that can be utilized to do bulk changes as one would need in such a situation. I wrote the code below to change the Alert Settings for ‘Base Page Status code’ unit monitor with a meaningful description. While this code is specific to changing alert settings on the Base page status code monitor, it can be applied to bulk editing any monitor setting.

The basic approach to editing monitor settings using SDK client is as follows

1.  Connect to the Management group

2. Construct a good set of criteria that will get you the monitor collection you want to apply the settings to

3. Retrieve the monitor collection

4. For each unit monitor in the collection, update the alert settings

5. Mark the ManagementPackElementStatus as PendingUpdate so it gets written back

6. Verify the changes

7. Apply the changes

 

using System;

using System.Collections.Generic;

using System.Collections.ObjectModel;

using System.Text;

using Microsoft.EnterpriseManagement;

using Microsoft.EnterpriseManagement.Administration;

using Microsoft.EnterpriseManagement.Common;

using Microsoft.EnterpriseManagement.Configuration;

using Microsoft.EnterpriseManagement.Monitoring;

 

 

namespace WebAlertDescription

{

    class Program

    {

        static void Main(string[] args)

        {

            ManagementGroup mg;

            ManagementPack mp;

            MonitoringClassCriteria classCriteria;

            MonitoringClass monitoringClass;

            MonitorCriteria monitorCriteria;

            ReadOnlyCollection <ManagementPackMonitor> monitors;

            mg = new ManagementGroup("MGTest");

            mp = mg.GetManagementPacks("Webtest")[0];

     

            classCriteria = new MonitoringClassCriteria("DisplayName='Foo test'");

 

            // Get the monitor collection of all Base page status code monitors

            monitoringClass = mg.GetMonitoringClasses(classCriteria)[0];

            monitorCriteria = new MonitorCriteria("DisplayName='Base Page Status Code'");

           

              

            // iterate for each request for monitors

            monitors = mg.GetMonitors(monitorCriteria);

            foreach (ManagementPackMonitor monitor in monitors)

            {

                UpdateAlertSettings(monitor, mp);

                monitor.Status = ManagementPackElementStatus.PendingUpdate;

            }

            mp.Verify();

 

            //Save the changes into the management pack.

            mp.AcceptChanges();

        }

 

        private static void UpdateAlertSettings(

                ManagementPackMonitor serviceMonitor,

                ManagementPack mp

        )

        {

           

            serviceMonitor.AlertSettings = new ManagementPackMonitorAlertSettings();

            serviceMonitor.AlertSettings.AlertOnState = HealthState.Error;

            serviceMonitor.AlertSettings.AutoResolve = true;

            serviceMonitor.AlertSettings.AlertPriority = ManagementPackWorkflowPriority.Normal;

            serviceMonitor.AlertSettings.AlertSeverity = ManagementPackAlertSeverity.MatchMonitorHealth;

            serviceMonitor.AlertSettings.AlertParameter1 = @"$Data/Context/RequestResults/RequestResult['1']/BasePageData/StatusCode$";            

 

            ManagementPackStringResource alertMessage;

 

            alertMessage = new ManagementPackStringResource(mp, "TESTSampleAlertMessage");

            alertMessage.DisplayName = "Status code message";

            alertMessage.Description = "Status code is {0}.";

                       

            serviceMonitor.AlertSettings.AlertMessage = alertMessage;

        }       

    }

}

A few notes about the above source code. This source code is a suggested example of bulk editing monitors. It also makes some simplistic assumptions of the selection of monitor criteria, updating the unit monitor settings and the application of changes to a management pack. This was intentional to keep the example short and succinct. For a more robust solution, you may want to customize it to apply changes to the appropriate management pack, for example.

The selection of monitoring criteria is based on Display Name. This returns all the monitors that match the display name. A more comprehensive solution should select the aggregate monitor for the Web application and use the monitor rollups to find the underlying unit monitor for ‘Base page status code’, or verify that the unit monitor for ‘base page status code’ has the proper target. In case of a name clash, it avoids overwriting the wrong monitor.

It took me a long time to realize why my changes were not being written back to the Management pack. The ManagementPackElementStatus needs to be set to PendingUpdate. Without this, the changes will not get persisted in the management pack.

A final note – a more desirable solution would be to have the aggregate monitor alert with the right alert description rather than enabling alert settings on all unit monitors. Now we end up with several unit monitor alerts in addition to the aggregate web application monitor alert – something we want to avoid. However, in the present design of monitors, it is not possible to get the context of the unit monitors at the aggregate monitor level. Hence, this is the best workaround available right now, until we add core functionality to create aggregate monitor context containing the unit monitor’s context. We are looking into that change for a future release.

 

For more information about the SDK, I would recommend checking out Jakub’s blog.

Comments
  • Is this code for a VB script or VB application?

    Cheers,

    Chad

  • This code is in C#.

  • If I wanted to update all monitors that contain request 1 how would I use a wildcard in the below? monitorCriteria = new MonitorCriteria("DisplayName='Base Page Status Code'");

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment