En Ru
Easy to use
GS Monitoring Framework

GS Monitoring Framework Tutorial


Here you can find a step-by-step example of using GS Monitoring Framework for .Net.

Let’s imagine we have some application that collects statistical data and writes it to the DB fields. Sometimes collection of data stops for unknown reason. The task is to find out when and why it happens.


Step 1


Include GS Monitoring Framework assembly file into project. If you still do not have GS Monitoring Framework for .Net please just fill in the field below and push the button. Our specialists will contact you.

My e-mail or phone:
 
 
Example: e-mail: [you@your.domain.name] or phone number with country code: [+375 017 259 19 11]


Privacy: Contact me form requires your e-mail or phone. We do not disclose, sell, rent or transfer your information to any third party. We use this information for getting in touch with you only.

Step 2


Add monitor initializer class. In this example we added a list of field names. In case of exception index of the field is replaced with the field name.
It is also possible to get etalon values from its storage with the help of initializer. For example getting of etalon time performance values from file.

using System.Collections.Generic;
using GersisSoftware.Gsmf.Initializers;
using GersisSoftware.Gsmf.Monitors;
using GersisSoftware.Gsmf.Settings;

namespace GersisSoftware.Gsmf.Sample
{
    /// <summary>
    /// Initializer for StatisticsServiceMonitor
    /// </summary>
    public class> StatServiceMonInitializer : AbstractInitializer
    {
        #region constructors
        /// <summary>
        /// Initialize new instance of monitor initializer
        /// <param name="aMonitorSettingsFactory">Settings factory used by monitor</param>
        public StatServiceMonInitializer(IMonitorSettingsFactory aMonitorSettingsFactory)
            : base(aMonitorSettingsFactory)
        {
        }
        #endregion

        /// <summary>
        /// Monitor initialization by reference values.
        /// </summary>
        /// <param name="aMonitor">the monitor which is necessary for initializing
        /// </param>
        public override void InitializeMonitor(IMonitor aMonitor)
        {
            List<string> fields = new List<string>();

            fields.Add("StatDate");
            fields.Add("CreatedModifications");

            StatServiceMonitor serviceMonitor = (StatServiceMonitor)aMonitor;
            serviceMonitor.FieldNames = fields;
        }
    }
}
 

Step 3


Add additional info class. In current example this class is used to store information about exception.

using System;
using GersisSoftware.Gsmf.Monitors;

namespace GersisSoftware.Gsmf.Sample
{
    /// <summary>
    /// Additinal information for StatisticsService
    /// </summary>
    public class StatServiceInfo : IInfoForMonitor
    {
        /// <summary>
        /// index of field that throw exception on update
        /// </summary>
        public int Field { get; set; }
        /// <summary>
        /// exception that has been thrown
        /// </summary>
        public Exception Exception { get; set; }

    }
}

Step 4


Add class of monitor that analyzes received information. In case of abnormal situation, data will be written to the desired destination (can be selected as adapter class in monitoring-settings.xml).
In this example abnormal situation is when exception parameter from StatisticsServiceInfo is not null.

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using GersisSoftware.Gsmf.Adapters;
using GersisSoftware.Gsmf.Monitors;

namespace GersisSoftware.Gsmf.Sample
{
           public class StatServiceMonitor : AbstractMonitor
           {
                   private class RunProcessParameter
                   {
                          public RunProcessParameter(object aMonitoredValue, IInfoForMonitor aAdditionalInfo)
                          {
                                  MonitoredValue = aMonitoredValue;
                                  AdditionalInfo = aAdditionalInfo;
                          }

                          public object MonitoredValue { get; set; }
                          public IInfoForMonitor AdditionalInfo { get; set; }
                  }

                  #region properties
                  private StatServiceInfo ServiceInfo;
                  private StatisticsService Service;
                  public List<string> FieldNames { get; set; }
                  #endregion

                  #region constructor
                  /// <summary>
                  /// Constructor of StatServiceMonitor class
                  /// </summary>
                  /// <param name="aName">monitor name</param>
                  /// <param name="aAdapters">adapters</param>
                  public StatServiceMonitor(string aName, List<IMonitorAdapter> aAdapters)
                        : base(aName, aAdapters)
                  {
                  }
                  #endregion

                  #region IMonitor methods
                  /// <summary>
                  /// Process monitored value
                  /// </summary>
                  /// <param name="statisticsService">monitored value</param>
                                          /// <exception cref="ArgumentException">statisticsService argument should ihnerits StatisticsService</exception>               
                  public override void
ProcessMonitoredValue(object statisticsService)
                  {
                      if (!(statisticsService is StatisticsService))
                          throw new ArgumentException("statisticsService argument should ihnerits StatisticsService");

                      ProcessMonitoredValue(statisticsService, null);
                   }

                   /// <summary>
                   /// Process monitored value
                   /// </summary>
                   /// <param name="statisticsService">monitored value</param>
                   /// <param name="statisticsServiceInfo">additional information</param>
                   /// <exception cref="ArgumentException">statisticsService argument should inherits StatisticsService</exception>
                   /// <exception cref="ArgumentException">statisticsServiceInfo argument should inherits StatServiceInfo</exception>
                   public override void ProcessMonitoredValue(object statisticsService, IInfoForMonitor statisticsServiceInfo)
                   {
                       if (!(statisticsService is StatisticsService))
                           throw new ArgumentException("statisticsService argument should inherits StatisticsService");
                       if (!(statisticsServiceInfo is StatServiceInfo))
                           throw new ArgumentException("statisticsServiceInfo argument should inherits StatServiceInfo");

                       ExecuteParallelProcessing(statisticsService, statisticsServiceInfo);
                   }

                   /// <summary>
                   /// Analyze MonitoredValue
                   /// </summary>
                   /// <param name="statisticsService">monitored value</param>
                   /// <param name="statisticsServiceInfo">additional information</param>
                   /// <exception cref="ArgumentException">statisticsService argument should inherits StatisticsService</exception>
                   /// <exception cref="ArgumentException">statisticsServiceInfo argument should inherits StatServiceInfo</exception>
                   public override void AnalyzeMonitoredValue(object statisticsService, IInfoForMonitor statisticsServiceInfo)
                   {
                       if (!(statisticsService is StatisticsService))
                           throw new ArgumentException("statisticsService argument should inherits StatisticsService");
                       if (!(statisticsServiceInfo is StatServiceInfo))
                           throw new ArgumentException("statisticsServiceInfo argument should inherits StatServiceInfo");

                       ////if StatisticsDAO is null than this is abnormal situation
                       //if (statisticsService.StatisticsDAO == null)
                       //{
                       //    Service = statisticsService;
                       //    OnAbnormalState();
                       //}
                       StatServiceInfo serviceInfo = statisticsServiceInfo as StatServiceInfo;
                       if (serviceInfo != null)
                       {
                           Exception exception = serviceInfo.Exception;
                           //if there is exception than this is abnormal situation
                           if (exception != null)
                           {
                               ServiceInfo = serviceInfo;
                               OnAbnormalState();
                           }
                        }
                  }
                  #endregion

                  #region AbstractMonitor

                  /// <summary>
                  /// Execute analyzing of monitored value in parallel thread
                  /// </summary>
                  /// <param name="statisticsService">monitored value</param>
                  /// <param name="statisticsServiceInfo">additional information</param>
                  protected override void ExecuteParallelProcessing(object statisticsService, IInfoForMonitor statisticsServiceInfo)
                 {
                      new Thread(RunProcess).Start(new RunProcessParameter(statisticsService, statisticsServiceInfo));
                 }

                 /// <summary>
                 /// Creates a copy of the monitor object
                 /// </summary>
                 /// <returns>Copy of the monitor object</returns>
                 protected override IMonitor GetCopy()
                 {
                     StatServiceMonitor copy = new StatServiceMonitor(Name, MonitorAdapters);
                     copy.Service = Service;
                     copy.ServiceInfo = ServiceInfo;
                     copy.FieldNames = FieldNames;
                     copy.AbnormalStateDescription = AbnormalStateDescription;

                     return copy;
                 }

                 /// <summary>
                 /// Creaates abnormal state description
                 /// </summary>
                 protected override void CreateAbnormalStateDescription()
                 {
                     StringBuilder description = new StringBuilder(DateTime.Now + " : StatisticsService fails.\n");

                     //if service not null than StatisticsDAO field is null
                     if (Service != null)
                     {
                         description.Append("Reason: StatisticsDAO is null\n");
                     }

                     //if serviceInfo not null, than there was exception while updating field
                    if (ServiceInfo != null)
                    {
                        description.Append("Reason: Exception on updating field StatisticsListener.").Append(FieldNames[ServiceInfo.Field]).Append(".");
                        description.Append("\nException: ").Append(ServiceInfo.Exception.ToString());
                    }

                    AbnormalStateDescription = description.ToString();
                 }
                 #endregion

                #region private methods
                private void RunProcess(Object obj)
                {
                    RunProcessParameter runProcessParameter = obj as RunProcessParameter;
                    if (runProcessParameter != null)
                    {
                        AnalyzeMonitoredValue(runProcessParameter.MonitoredValue, runProcessParameter.AdditionalInfo);
                    }
                }
                #endregion

    }
}

Step 5


Add GSMF configuration section to the application configuration file.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
      <configSections>
            <section name="Gsmf" type="GersisSoftware.Gsmf.Settings.GsmfSection, GersisSoftware.Gsmf" restartOnExternalChanges="true" />
      </configSections>
      <Gsmf>
            <monitors>
                  <clear/>
                  <add name="StatServiceMonitor" type="GersisSoftware.Gsmf.Sample.StatServiceMonitor">
                        <adapters>
                              <clear/>
                              <add type="GersisSoftware.Gsmf.Adapters.FileLogMonitorAdapter" />
          <add type="GersisSoftware.Gsmf.Adapters.ConsoleLogMonitorAdapter" />
                        </adapters>
                        <initializer type="GersisSoftware.Gsmf.Sample.StatServiceMonInitializer,
GersisSoftware.Gsmf.Sample">
                        </initializer>
                        <parameters>
                              <clear/>
          <add name ="master_value" value="100"/>
          <add name ="master_delta" value="10"/>
                        </parameters>
                        </add>
             </monitors>
      </Gsmf>
</configuration>

Step 6


Add code, that collects information, to the potentially problematic points. Code inserted for monitoring purposes is marked yellow.
 
var monitor =
MonitorManager.Instance.GetMonitor<StatServiceMonitor>("StatServiceMonitor");


Trace.TraceInformation("Regular statistics collection.");
StatisticsService statistics = new StatisticsService();

int field = 0;
Exception exception = null;

//Add try/catch block to catch Exception (if it will be thrown)
try
{
      statistics.StatDate = DateTime.Now.Ticks;
      field++;
      statistics.CreatedModifications();
      field++;
}
catch (Exception e)
{
       exception = e;
}
finally
{
       //Process information about exception to the monitor
       StatServiceInfo info = new StatServiceInfo()
                              {
                                    Exception = exception, Field = field
                              };
       monitor.ProcessMonitoredValue(this, info);
}

Step 7


Messages from the monitor will be stored to the file “monitoring.log”. It is located in the root folder of application.