ho funzionato, anche se non era davvero semplice.
prima di tutto devo apportare alcune correzioni alle mie dichiarazioni precedenti - solo per essere sullo stesso livello.
Nel Servizio Cloud ci sono diverse macchine virtuali, ognuna delle quali ospita un'istanza WebRole o un'istanza WorkerRole. Quindi su una singola VM viene eseguito solo un singolo w3wp o nessun w3wp, tranne un processo waworkerhost.
Nel mio caso speciale c'è la possibilità di avere due w3wp in esecuzione su una singola VM. quindi avevo bisogno di distinguere tra questi due, quindi mi richiedevano di creare una sorta di associazione di istanza di processo.
Quello che volevo registrare era: Il carico totale della CPU di una singola VM, il carico della CPU del processo istanza in esecuzione sulla VM (w3wp, waworkerhost).
Il PerformanceCounter per Load CPU totale è facile ed uguale per ogni VM: \ Processore (_Total) \% Processortime per la WebRole VM ho potuto basta utilizzare il processo \ (w3wp) \% processortime contatore perché non posso essere sicuro se è il w3wp corretto (vedi sopra)
Ora ecco cosa ho fatto: Dato che devi avviare un contatore di prestazioni contatore per ogni istanza di ruolo OnStart() in WebRole.cs o WorkerRole.cs ho capito questo è l'unico posto dove posso in qualche modo raccogliere le informazioni richieste.
Negli WorkerRole.cs ho fatto:
int pc = Environment.ProcessorCount;
string instance = RoleEnvironment.CurrentRoleInstance.Id;
SomeOtherManagementClass.StartDiagnosticMonitorService(pc, instance, Process.GetCurrentProcess());
Negli WebRole.cs il CurrentProcess restituisce anche WaWorkerHost, così ho dovuto spostare le codeline sopra nella global.asax del WebRole. Qui è disponibile il Processo corretto.
In SomeOtherManagementClass ho inserito StartDiagnosticsMonitorService, che ora riceve il CurrentProcess da cui è stato chiamato StartDiagnosticsMonitorService. (da workerrole.cs riceverebbe WaWorkerHost processo e dal WebRoles processo w3wp - compreso 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) viene ora chiamato ogni VM e ottiene il processName alla condizione process.Id - questo consente di effettuare una differenziazione tra più w3wps su una singola VM poiché i nomi di istanza restituiti sono w3wp, w3wp # 1, w3wp # 2 ecc., contrariamente al processName fornito da GetCurrentProcess, che è sempre w3wp. per questo ho modificato un codeSample ho trovato qui su StackOverflow - si può trovare qui di seguito:
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 "";
}
Ultimo ma non meno importante: SetCPUCoreData (coreCount, currentRole, processName, process.Id) salva tutti i dati rilevanti dei processi allo stoccaggio azzurro quindi è disponibile da ovunque nell'applicazione:
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);
}
il PerformanceCounterCPUCoreEntity è un modello per lo StorageTable - esaminare l'API bagagli azzurro se avete domande riguardo a questa parte, o semplicemente chiedere.