Define a w3wp related process for a web role instance

I am working on monitoring the performance of the Azure service.

Two instances of the web role are currently running (for the same site) - each with its own W3WP.exe (w3wp and w3wp # 1)

How do I know which w3wp process belongs to an instance of roles?

Using this information, I want to file the azure.diagnostics.monitor file with some performance counters, namely Process (w3wp) \ ProcessorTime (%) and Thread Count. But to get any meaningful data, I have to add the process identifier of the w3wp process to the performance counter (for example, Process (w3wp_PID) \ processorTime (%)) - I don’t know if the syntax is correct, but there is a way to add PID)

therefore, the final result in the AzureStorage WADPerformanceCounters table has only entries:

WebRoleInstance_n_0 | process(w3wp_1033)\processorTime (%) | 12.4 WebRoleInstance_n_1 | process(w3wp_1055)\processorTime (%) | 48.4 

atm its like

 WebRoleInstance_n_0 | process(w3wp)\processorTime (%) | 12.4 WebRoleInstance_n_1 | process(w3wp)\processorTime (%) | 12.4 

I thought: if I started DiagnosticsMonitor for each role, the monitor would use the correct process - owned by Roleinstance, which started the monitor. but it really doesn't work - or I think it doesn't work - at least after looking at the resulting values.

// update: on the manage.windowsazure portal you can define your own indicators for monitoring performance. Here you can select a webrole instance that will be monitored exclusively. This is what I want too. Understanding what this page can really do can also help.

for comparison: http://puu.sh/1xp7q

They are just silly ways, I can think of to get this information: to get a list of all processes before and after starting each w3wp - determine which one was added, and then decide the context of the code base, which instance of the role was just started.

+6
source share
1 answer

It worked for me - although it was not so simple.

First of all, I have to make some corrections to my previous statements - just to be on the same level.

There are several virtual machines in the cloud service, each of which has either a WebRole instance or a WorkerRole instance. Thus, on one virtual machine, only one w3wp is launched or does not have w3wp at all, except for the waworkerhost process.

In my special case, it is possible to have two w3wp running on the same virtual machine. so I needed to distinguish between the two - so I demanded that I make some kind of association of instance processes.

What I wanted to register was: general CPU utilization of one VM, processor load of an instance process running on a virtual machine (w3wp, waworkerhost).

PerformanceCounter to fully load the CPU is easy and equal for each virtual machine: \ Processor (_Total) \% Processortime for webrole VM I just could not use the counter \ process (w3wp) \% processortime, because I can not be sure that it is correct w3wp (see above)

Now here's what I did: Since you have to run the performance counter monitor for each instance of the OnStart () role in WebRole.cs or WorkerRole.cs, I decided that this is the only place where I can somehow collect the necessary information.

In WorkerRole.cs, I did:

 int pc = Environment.ProcessorCount; string instance = RoleEnvironment.CurrentRoleInstance.Id; SomeOtherManagementClass.StartDiagnosticMonitorService(pc, instance, Process.GetCurrentProcess()); 

In WebRole.cs, CurrentProcess also returns WaWorkerHost, so I had to move the above codes to global.asax WebRole. The correct process is available here.

In SomeOtherManagementClass, I put the StartDiagnosticsMonitorService, which now receives the CurrentProcess from which StartDiagnosticsMonitorService was called. (from workerrole.cs he will receive the WaWorkerHost Process and WebRoles - the w3wp process - including the PID)

 public static void StartDiagnosticMonitorService(int coreCount, string currentRole, Process process) { string processName = GetProcessInstanceName(process.Id); SetCPUCoreData(coreCount, currentRole, processName, process.Id); ... instanceProcessLoadCounterName = String.Format(@"\Process({0})\% Processor Time", processName); } 

GetProcessInstanceName (process.Id) is now called in each virtual machine and gets the process name for the provided process. Id This allows you to differentiate between multiple w3wps on the same virtual machine, because the returned instances are returned by w3wp, w3wp # 1, w3wp # 2, etc., unlike the processName provided by GetCurrentProcess, which is always w3wp. To do this, I changed the code I found here in stackoverflow - you can find it below:

 private static string GetProcessInstanceName(int pid) { PerformanceCounterCategory cat = new PerformanceCounterCategory("Process"); string[] instances = cat.GetInstanceNames(); foreach (string instance in instances) { try { using (PerformanceCounter cnt = new PerformanceCounter("Process", "ID Process", instance, true)) { int val = (int)cnt.RawValue; if (val == pid) { return instance; } } } catch (InvalidOperationException) { //this point is reached when a process terminates while iterating the processlist- this it cannot be found } } return ""; } 

And last but not least: SetCPUCoreData (coreCount, currentRole, processName, process.Id) saves all the relevant process data in the azure storage, so it is available anywhere in the application:

 private static void SetCPUCoreData(int count, string roleinstance, string processName, int processID) { string[] instances = roleinstance.Split('.'); CloudStorageAccount storageAccount = CloudStorageAccount.Parse(GetSettingValue("LoadMonitor.Connection.String")); CloudTableClient cloudTableClient = storageAccount.CreateCloudTableClient(); const string tableName = "PerformanceMonitorCoreCount"; cloudTableClient.CreateTableIfNotExist(tableName); TableServiceContext serviceContext = cloudTableClient.GetDataServiceContext(); PerformanceCounterCPUCoreEntity ent = new PerformanceCounterCPUCoreEntity(count, instances[instances.Count() - 1],processName, processID); serviceContext.AttachTo(tableName, ent); serviceContext.UpdateObject(ent); serviceContext.SaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate); } 

PerformanceCounterCPUCoreEntity is a template for StorageTable - take a look at the azure storage API if you have any questions about this part or just ask.

0
source

All Articles