Entrepreneurs and Innovators Driving the Technology Community

Entrepreneurs

Subscribe to Entrepreneurs: eMailAlertsEmail Alerts newslettersWeekly Newsletters
Get Entrepreneurs: homepageHomepage mobileMobile rssRSS facebookFacebook twitterTwitter linkedinLinkedIn


As can be seen in Figure 4 above the Web Role contains ASPX files and a WebRole class. In this example the WebRole class is triggered on startup of the application. This simple default web application can be executed within your local environment i.e. within the Windows Azure Compute Emulator.

Figure 6 – The default web application

Step 4 – Configure the Diagnostic Monitor for this application

Configure the diagnostic monitor from within the class WebRole.cs.  Create a method called ConfigureDiagnosticMonitor to hold the configuration settings of the Diagnostic Monitor. Call the method from within the OnStart method which runs code which initializes a role instance.

//The connection string is defined within the file ServiceConfiguration.Cloud.cscfg

private readonly string wadConnectionString = "Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString";

public override bool OnStart()

{

this.ConfigureDiagnosticMonitor();

return base.OnStart();

}

private void ConfigureDiagnosticMonitor()

{

//Get reference to the initial default configuration.

//Use this reference to effect changes to the default configuration

DiagnosticMonitorConfiguration dMC =

DiagnosticMonitor.GetDefaultInitialConfiguration();

//Configure monitoring of a Windows performance counter

//Add it to the configuration

PerformanceCounterConfiguration pCC = new PerformanceCounterConfiguration();

pCC.CounterSpecifier = @"\Processor(_Total)\% Processor Time";

//get a reading every 10 seconds

pCC.SampleRate = System.TimeSpan.FromSeconds(10d);

dMC.PerformanceCounters.DataSources.Add(pCC);

//trasfer scheduled to every 1 minute

dMC.PerformanceCounters.ScheduledTransferPeriod = TimeSpan.FromMinutes(1d);

//Start the diagnostic monitor

DiagnosticMonitor.Start(wadConnectionString, dMC);

}

On executing the application the Diagnostic Monitor will gather Processer Time data and store it in the local storage of the Web Role. At 1 minute intervals the data will be transfered to persistent storage.

Now proceed to set the Instance Count of the Web Role to 2. When the application is deployed 2 instances of the Web Role will be launched by Windows Azure.

Step 5 – Specify the number of role instances to deploy

Figure 7 – Set the Instance Count to 2

Click on MonitisWebRole1 to access its configuration settings. Set the Instance Count to 2. Diagnostic data will be gathered for both instances. Figure 8 below displays data gathered from 2 instances.

Step 6 – Define the Windows Azure Storage account.

The connection string which determines the storage location where diagnostics data will be stored is set within your ServiceConfiguration.cscfg

Whilst working within your development environment the development storage on the local envrioment can be used.

The connection string for persistent storage of diagnostics data can be set to local Development Storage during the development cycle of the application

<ConfigurationSettings>

<Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString"   value="UseDevelopmentStorage=true" />

</ConfigurationSettings>

Once the application is ready for deployment onto Windows Azure is is essential to point the persistent storage to your Windows Azure Storage Account.

For persistent storage of diagnostics data on the cloud, set the connection string to point to your cloud storage account

<ConfigurationSettings>

<Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" value="DefaultEndpointsProtocol=http;

AccountName=accountName;

AccountKey=accountKey" />

</ConfigurationSettings>

The screenshot below depicts data from table WADPerformanceCountersTable. The table will be created in the Windows Azure Storage account to which the Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString points.

Figure 8  – Performance Counter data which has been gathered for 2 instances

Read the data and post to your Monitis Account.

Thus far we have created an ASP.NET Web Application which contains 1 Web Role. The Web Role serves to provide the user interface. We have configured the Diagnostic Monitor to collect CPU utilization perforance counter data. This data will be persisted in the table WADPerformanceCountersTable in the Windows Azure storage account which is specified within the file ServiceConfiguration.cscfg

Step 1 – Create a Worker Role

Create a Worker Role to execute a background process which will:

  • create a custom monitor within a Monitis account
  • read the data from table WADPerformanceCountersTable
  • post the data to the custom monitor

 

Figure 9  – Click on Roles and add a Worker Role project.

Select C#, set the name of the Worder Role and press Add

Figure 10  – Adding a Worker Role

The Worker Role is now created as displayed in the Solution Explorer below.

Figure 11  – Worker Role created

Proceed to place the following code within the class WorkerRole.cs

Step 2 – Create the custom monitor within Monitis

Place the following code within the Run method of class WorkerRole

Add the following class variables. The apiKey and secretKey values have to be retrieved from yoru Monitis account.

private readonly string wadConnString = "Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString";

//You API key and Secret Key

private String apiKey = "2C73GGQ8QGBKVGPJI9R5U4M811";

private String secretKey = "35JC0OC26OS2FV5DBKED16UF31";

private String monitorAbailableMemoryID;

Add the following code to the Run method

public override void Run()

{

//request authorisation token from your Monitis account

String authToken = requestAuthToken();

//add a custom monitor to you Monitis account and get the id of the custom Monitor

monitorAbailableMemoryID = addCustomMonitor1(authToken);

}//end Run

Call the method requestAuthToken to retrieve a security token from Monitis. This token will be used to post requests to the Monitis service.  Place the following code within WorkerRole class

private String requestAuthToken()

{

String url = "http://www.monitis.com/api?action=authToken&apikey=" + apiKey +

"&secretkey=" + secretKey;

WebRequest request = WebRequest.Create(url);

request.Method = "GET";

WebResponse response = request.GetResponse();

Stream dataStream = response.GetResponseStream();

StreamReader reader = new StreamReader(dataStream);

string responseFromServer = reader.ReadToEnd();

response.Close();

String authToken = DissectAuthString("authToken", responseFromServer);

return authToken;

}//end requestAuthToken

The method DissectAuthString is called from by methos RequestAuthToken

private String DissectAuthString(String keyString, String cString)

{

String dissected = "";

cString = cString.Remove(0, keyString.Length + 5);

int pos = cString.IndexOf("\"}");

dissected = cString.Remove(pos, 2);

return dissected;

}

The following method uses the supplied token to create a custom monitor and returns the ID of the monitor. The ID of the monitor will be used to identify the monitor to which data will be posted. This is essential as more than one custom monitor may be created within a Monitis account.

private String addCustomMonitor(String authToken)

{

String url = "http://www.monitis.com/customMonitorApi";

String monitorParams =     "PerfCtrs_data:ProcessorTime:Processor+time+records:3:false;";

String resultParams = "processorTime:ProcessorTime:N%2FA:2;";

String name = "Processor Time";

String tag = "[perfctrs+processortime]";

//build the request

WebRequest request = WebRequest.Create(url);

request.Method = "POST";

String postData = "apikey=" + apiKey + "&validation=token&authToken=" + authToken + "&timestamp=" + "2012-03-09 20:00:00" + "&action=addMonitor&monitorParams=" + monitorParams + "&resultParams=" + resultParams + "&name=" + name + "&tag=" + tag;

byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(postData);

request.ContentType = "application/x-www-form-urlencoded";

request.ContentLength = byteArray.Length;

Stream dataStream = request.GetRequestStream();

dataStream.Write(byteArray, 0, byteArray.Length);

dataStream.Close();

//get the response

WebResponse response = request.GetResponse();

dataStream = response.GetResponseStream();

StreamReader reader = new StreamReader(dataStream);

String responseFromServer = reader.ReadToEnd();

response.Close();

return DissectMonitorIDFromStatusString1("status\":\"ok\",\"data",                                             responseFromServer);

}// end addCustomMonitor

The following method is called from method addCustomMonitor

private String DissectMonitorIDFromStatusString1(String keyString, String cString)

{

String dissected = "";

cString = cString.Remove(0, keyString.Length + 4);

int pos = cString.IndexOf("}");

dissected = cString.Remove(pos, 1);

return dissected;

}

At this stage the application can be executed within the local environment. The Worker Role would retrieve an authorisation token from Monitis and use the token to create a custom monitor within Monitis

Figure 12  – Custom Monitor created by method addCustomMonitor

Step 3 – Read data from storage and post to custom monitor

Amend the Run method.  Add code to post data to your custom monitor.

public override void Run()

{

//request authorisation token from your Monitis account

String authToken = requestAuthToken();

//add a custom monitor to you Monitis account and get the id of the custom Monitor

monitorAbailableMemoryID = addCustomMonitor1(authToken);

while (true)

{

//sleep for 5 minutes

Thread.Sleep(300000);

//loop through the diagnostic data and post to custom monitor

loopThroughData(authToken);

}

}//end Run

private void loopThroughData(String _token)

{

double testTime;

//get referene to the cloud storage account

CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue(wadConnString));

CloudTableClient cloudTableClient = cloudStorageAccount.CreateCloudTableClient();

//get ticks as at previous 10 minutes

DateTime now = DateTime.UtcNow;

DateTime tenMinutesAgo = now.AddMinutes(-10);

string partitionKeyNow = string.Format("0{0}", now.Ticks.ToString());

string partitionKeyTenMinutesAgo = string.Format("0{0}",   tenMinutesAgo.Ticks.ToString());

TableServiceContext tableServiceContext = cloudTableClient.GetDataServiceContext();

tableServiceContext.ResolveType = (unused) => typeof(WadPerformanceCountersTable);

//retrieve rows generated during the last 10 mminutes

CloudTableQuery<WadPerformanceCountersTable> cloudTableQuery =

(from entity in tableServiceContext.CreateQuery<WadPerformanceCountersTable>("WADPerformanceCountersTable") where entity.PartitionKey.CompareTo(partitionKeyNow) < 0 && entity.PartitionKey.CompareTo(partitionKeyTenMinutesAgo) > 0 select entity).Take(1000).AsTableServiceQuery();

List<WadPerformanceCountersTable> performanceCountersEntitiesList = null;

try

{

performanceCountersEntitiesList =  cloudTableQuery.Execute().ToList<WadPerformanceCountersTable>();

}

catch (DataServiceQueryException dsqe)

{

System.Diagnostics.Trace.TraceError(dsqe.Message);

}

//loop through performance counter records and post data to custom monitor

foreach (WadPerformanceCountersTable perfCounterRecord in performanceCountersEntitiesList)

{

testTime = (perfCounterRecord.EventDateTime - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds;

testTime = Math.Ceiling(testTime) * 1000;

postValue(_token, performanceCounterMonitorID, perfCounterRecord.CounterValue.ToString(), testTime.ToString(), "processorTime");

}

}//end loopThroughData

Method loopThroughData calls the following method to post data to the Monitis Service.

private void postValue(String authToken, String _monitorId, String _valueToPost, String _checkTime, String _resultType)

{

String url = "http://www.monitis.com/customMonitorApi";

String action = "addResult";

String results = _resultType + ":" + _valueToPost + ";";

String unixDate = _checkTime;

WebRequest request = WebRequest.Create(url);

request.Method = "POST";

request.ContentType = "application/x-www-form-urlencoded";

String postData = "apikey=" + apiKey + "&validation=token&authToken=" + authToken + "&timestamp=" + "2012-03-11 10:00:00" + "&version=2" + "&action=" + action + "&monitorId=" + _monitorId + "&checktime=" + unixDate + "&results=" + results;

byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(postData);

request.ContentType = "application/x-www-form-urlencoded";

request.ContentLength = byteArray.Length;

Stream dataStream = request.GetRequestStream();

dataStream.Write(byteArray, 0, byteArray.Length);

dataStream.Close();

//get the response

WebResponse response = request.GetResponse();

dataStream = response.GetResponseStream();

StreamReader reader = new StreamReader(dataStream);

String responseFromServer = reader.ReadToEnd();

response.Close();

}//end postValue

On executing the Windows Azure application which we have created above:

  • CPU utilization will be recorded into persistent storage
  • A custom monitor will be created
  • Data will be posted to the custom monitor

The image below displays the outcome of all the above

Figure 13  – Custom Monitor populated with Processor Time

 

More Stories By Hovhannes Avoyan

Hovhannes Avoyan is the CEO of PicsArt, Inc.,

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.