我得到了它的工作 - allthough它并不真正直接。
首先,我必须对我以前的陈述进行一些更正 - 只是要在同一水平上。
在Cloud Service中,有几个虚拟机,每个虚拟机承载WebRole实例或WorkerRole实例。 因此,在一台虚拟机上,只有一个w3wp运行,或者根本没有w3wp,只有一个waworkerhost进程。
在我的特殊情况下,可能会在单个虚拟机上运行两个w3wp。所以我需要在这两者之间进行区分 - 因此需要我进行某种过程 - 实例关联。
我想记录的是:单个VM的总CPU负载,VM上运行的实例进程的CPU负载(w3wp,waworkerhost)。
对于每个虚拟机,CPU负载的PerformanceCounter很容易和相等:\ Processor(_Total)\%Processortime 对于webrole VM,我不能只使用\ process(w3wp)\%processortime counter,因为我不能知道它的正确的w3wp(见上文)
现在,这里是我做过什么: 既然你在WebRole.cs或WorkerRole.cs开始为每个角色实例的OnStart(性能计数器监视器)我想通了这是我能以某种方式收集所需信息的唯一地方。
在WorkerRole.cs我所做的:
int pc = Environment.ProcessorCount;
string instance = RoleEnvironment.CurrentRoleInstance.Id;
SomeOtherManagementClass.StartDiagnosticMonitorService(pc, instance, Process.GetCurrentProcess());
在WebRole.cs的CurrentProcess也返回WaWorkerHost,所以我不得不上面的代码行移动到WebRole的Global.asax中。这里有正确的过程可用。
在SomeOtherManagementClass中,我放置了StartDiagnosticsMonitorService,它现在接收调用StartDiagnosticsMonitorService的CurrentProcess。 (从workerrole.cs它将收到WaWorkerHost过程与从WebRoles w3wp进程 - 包括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)现在被称为上的每个VM,并获取processName所提供process.Id - 这允许您在单个虚拟机上区分多个w3wps,因为与由GetCurrentProcess提供的processName(它是allways w3wp)相反,返回的instanceNames是w3wp,w3wp#1,w3wp#2等。为了这个,我修改了codesample我发现这里的计算器 - 你可以在下面找到它:
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 "";
}
最后但并非最不重要的:SetCPUCoreData(coreCount,currentRole,processName,process.Id)保存过程中的所有相关数据到Azure存储,因此可从无处不在的应用程序:
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对于StorageTable模板 - 窥视Azure存储API,如果你有任何关于这部分有任何疑问,或只问。