我得到了它的工作 - 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,如果你有任何關於這部分有任何疑問,或只問。