私はそれを稼働させました。しかし、それは本当にまっすぐではありませんでした。
まず、前のステートメントにいくつかの修正を加えなければなりません。同じレベルにするだけです。
クラウドサービスには、それぞれWebRoleインスタンスまたはWorkerRoleインスタンスのいずれかをホストする複数の仮想マシンがあります。 したがって、単一のVMでは、w3wpが1つだけ実行されるか、w3wpは実行されませんが、waworkerhostプロセスは実行されません。
私の特別なケースでは、1つのVMで2つのw3wpを実行する可能性があります。だから私はそれらの2つを区別する必要があったので、ある種のプロセスインスタンスの関連付けが必要になった。
ログに記録したいのは、単一のVMの合計CPU負荷、VM上で実行されているインスタンスプロセスのCPU負荷(w3wp、waworkerhost)です。
合計CPU負荷のPerformanceCounterは各VMで簡単です。\ Processor(_Total)\%Processortime webrole VMの場合、\ process(w3wp)\%processortimeカウンタは使用できませんでした。 WebRole.csまたはWorkerRole.csの各ロールインスタンスOnStart()に対してパフォーマンスカウンターモニターを開始する必要があるため、これを考えました私は何とか必要な情報を収集できる唯一の場所です。私がやったWorkerRole.csで
:WebRole.csで
int pc = Environment.ProcessorCount;
string instance = RoleEnvironment.CurrentRoleInstance.Id;
SomeOtherManagementClass.StartDiagnosticMonitorService(pc, instance, Process.GetCurrentProcess());
CurrentProcessもWaWorkerHostを返しますので、私はWebRoleのGlobal.asaxのに上記のコードラインを移動しなければなりませんでした。ここで正しいプロセスが利用可能です。
SomeOtherManagementClassには、StartDiagnosticsMonitorServiceが呼び出されたCurrentProcessを受け取るStartDiagnosticsMonitorServiceが置かれています。 (workerrole.csからそれがW3WPプロセスWaWorkerHostプロセスを受け取り、WebRolesからなる - 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上で呼び出されて提供process.IdにProcessNameのを取得していますこれは、GetCurrentProcessによって提供されるprocessName(これは常にw3wp)とは対照的に、返されるinstanceNamesがw3wp、w3wp#1、w3wp#2などであるため、単一のVM上で複数のw3wpsを区別することができます。このために私はstackoverflowの上でここに見つける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に見て、あるいは単に尋ねます。