This project is read-only.

Walkthru - Creating a HealthCheck component


 
abc.png This is a step-by-step guide to creating a new custom HealthCheck component and includes instructions on getting this running in MonitorWang and reporting its data.

UPDATE MonitorWang is now on NuGet! Rob Gibbens has created the NuGet packages to support & streamline custom HealthCheck and Publisher development. These contain just the binaries required to develop either of these plugins for MonitorWang. You can get the packages from the NuGet gallery using the links below or via the online package browser in Visual Studio - just search for "MonitorWang"......
Publisher Package
HealthCheck Package

Thanks Rob, great job!

NOTE MonitorWang is written in C# targeting the v3.5 .Net framework.

All of the following can be found in the "HelloWorldHealthCheck" project in the Source code zip. The binding and check configuration file updates are also included but commented out. The fast start version is this,
1. Get the source and unzip
2. Uncomment the "Demo walk-thru component" in the Config\binding.castle.config file
3. Uncomment the "Demo walk-thru component" in the Config\check.castle.config file
4. Build the solution
5. Copy the HelloWorldHealthCheck.dll from HelloWorldHealthCheck\bin\debug into MonitorWang.Agent\bin\debug
6. Start MonitorWang from the command line with "MonitorWang.Agent.exe"

Creating the HealthCheck

1. Create a new class library project called "HelloWorldHealthCheck"
2. Add a reference to MonitorWang.Core.dll & MonitorWang.Core.Interfaces.dll
3. Rename "Class1" to "HelloWorldCheck" and make it implement IHealthCheckPlugin (MonitorWang.Core.Interfaces namespace)
4. Add a new class called "HelloWorldCheckConfig". The name is important as a convention is used to match HealthCheck configuration with HealthChecks - THE CONFIGURATION CLASSNAME MUST BE HealthCheckClassNameConfig
5. Make "HelloWorldCheckConfig" inherit from "HealthCheckConfigBase"
6. Add a property to "HelloWorldCheckConfig", the config class should look like...
public class HelloWorldCheckConfig : HealthCheckConfigBase
{
    public string MyCustomSetting { get; set; }
}
7. Add a private readonly member variable of type "HelloWorldCheckConfig" called "myConfig" to "HelloWorldCheck"
private readonly HelloWorldCheckConfig myConfig;
8. Add a constructor to "HelloWorldCheck" - this should take our config class as the only parameter.
public HelloWorldCheck(HelloWorldCheckConfig config)
{
    myConfig = config;
}
9. Implement the "Status" property as an "Auto-Property". This is used by MonitorWang to track the state of a component during startup. MonitorWang will report any components that fail to initialise properly and disable them.
public Status Status { get; set; }
10. Implement the "Identity" property on "HelloWorldCheck"
public PluginDescriptor Identity
{
    get { return new PluginDescriptor
    {
        Description = "My first custom HealthCheck!",
        Name = myConfig.FriendlyId,
        // The TypeId is important - it needs to be different for
        // each health check as this allows us to positively identify
        // every health check. Use the VS Tools/Create GUID tool to
        // generate a new one.
        TypeId = new Guid("218087BB-3605-4fa5-9157-0C133674F51F")
    }; }
}
11. Implement the "Execute()" method on "HelloWorldCheck"
public void Execute()
{
    Messenger.Publish(new HealthCheckData
    {
        Identity = Identity,
        Result = true,
        Info = string.Format("MyCustomSetting:={0}", myConfig.MyCustomSetting)
    });
}
12. The "Initialise()" method on "HelloWorldCheck" should do nothing
public void Initialise()
{
    // This can be used to do any "one-time" initialisation
    // of this check - this method is called when the plugin
    // is loaded (must also be "enabled" in its configuration)
}

The finished health check should look like this,
using System;
using MonitorWang.Core.Interfaces;
using MonitorWang.Core.Interfaces.Entities;

namespace HelloWorldHealthCheck
{
    public class HelloWorldCheckConfig : HealthCheckConfigBase
    {
        public string MyCustomSetting { get; set; }
    }

    public class HelloWorldCheck : IHealthCheckPlugin
    {
        private readonly HelloWorldCheckConfig myConfig;

        public HelloWorldCheck(HelloWorldCheckConfig config)
        {
            myConfig = config;
        }

        public void Initialise()
        {
            // This can be used to do any "one-time" initialisation
            // of this check - this method is called when the plugin
            // is loaded (must also be "enabled" in its configuration)
        }

        public Status Status { get; set; }

        public PluginDescriptor Identity
        {
            get { return new PluginDescriptor
                             {
                                 Description = "My first custom HealthCheck!",
                                 Name = myConfig.FriendlyId,
                                 // The TypeId is important - it needs to be different for
                                 // each health check as this allows us to positively identify
                                 // every health check. Use the VS Tools/Create GUID tool to
                                 // generate a new one.
                                 TypeId = new Guid("218087BB-3605-4fa5-9157-0C133674F51F")
                             }; }
        }

        public void Execute()
        {
            Messenger.Publish(new HealthCheckData
                        {
                            Identity = Identity,
                            Result = true,
                            Info = string.Format("MyCustomSetting:={0}", myConfig.MyCustomSetting)
                        });
        }

        public event PublishHandler Publish;
    }
}
12. Compile the "HelloWorldHealthCheck" project and copy the "HelloWorldHealthCheck.dll" (and .pdb) to the MonitorWang binaries folder.

Configuring the HealthCheck

1. In the MonitorWang binaries folder is a sub-folder called "Config". Locate and open the "check.castle.config" file.
2. Add a new "component" - ensure it is between the "components" tags,
<component id="MyHelloWorldCheckConfig"
	   lifestyle="singleton"
	   type="HelloWorldHealthCheck.HelloWorldCheckConfig, HelloWorldHealthCheck">
  <parameters>
    <MyCustomSetting>Hello World!!</MyCustomSetting>
    <FriendlyId>HelloWorldCheck</FriendlyId>
    <Enabled>true</Enabled>
  </parameters>
</component>
3. In the MonitorWang binaries folder is a sub-folder called "Config". Locate and open the "binding.castle.config" file.
4. Add a new "component" - ensure it is between the "components" tags,
<component id="HelloWorldCheckBindingConfig"
	   lifestyle="singleton"
	   type="MonitorWang.Core.Interfaces.Entities.BindingConfiguration, MonitorWang.Core.Interfaces">
  <parameters>
    <HealthCheckConfigurationName>MyHelloWorldCheckConfig</HealthCheckConfigurationName>
    <ScheduleConfigurationName>EveryMinute</ScheduleConfigurationName>
  </parameters>
</component>
The HealthCheckConfigurationName value is "MyHelloWorldCheckConfig" - this is the same name we used in step 2; the binding links us to our new health check configuration component. This configuration component is linked to our custom health check implementation by a naming convention - MonitorWang infers the class name of the HealthCheck by stripping "Config" from the end of the configuration component class name. The same is true with the binding "ScheduleConfigurationName" value - however this leads to a "Scheduler" configuration component in the "scheduler.castle.config" file and then onto a "Scheduler" implementation via the same naming convention.

Binding.HealthCheckConfigurationName -> MyHelloWorldCheckConfig configuration component ->"HelloWorldCheckConfig" class = "HelloWorldCheck" HealthCheck class.

An instance of "HelloWorldCheck" is created and supplied with our "HelloWorldCheckConfig" configuration instance ("MyHelloWorldCheckConfig").


Start MonitorWang - your check "HelloWorldCheck" should now be running & publishing new results every 60 seconds.

Last edited May 15, 2011 at 6:54 AM by jimbobdog, version 24

Comments

jimbobdog Mar 21, 2011 at 8:37 AM 
Thanks to gibbensr - configuration namespace relocation now fixed!