Technology Experience

Contenuti gestiti da Igor Damiani
posts - 949, comments - 2741, trackbacks - 15120

My Links

News

  • Questo blog si propone di raccogliere riflessioni, teoriche e pratiche, su tutto quello che riguarda il world-computing che mi sta attorno: programmazione in .NET, software attuale e futuro, notizie provenienti dal web, tecnologia in generale, open-source.

    L'idea è quella di lasciare una sorta di patrimonio personale, una raccolta di idee che un giorno potrebbe farmi sorridere, al pensiero di dov'ero e cosa stavo facendo.

    10/05/2005,
    Milano

Archives

Post Categories

Generale

PerformanceCounter per provocare il power-off dell'OS

Introduzione
Tra venerdì e questa mattina ho risolto un problema che da parecchio tempo assillava il Tech-Team, la squadra di esperti IT certificati MS/Oracle interna all'azienda dove lavoro. Immaginate lo scenario: un super-server - di cui purtroppo non so darvi le caratteristiche hardware precise - su cui gira Virtual Server 2005, in grado di ospitare qualcosa come circa una quindicina di macchine virtuali attive più o meno contemporaneamente. Il problema è che molto spesso queste VM rimangono attive anche quando non effettivamente necessarie, rubando memoria e risorse a tutte le altre.

Il Tech-Team ha ricercato per molto tempo in rete un'utility che potesse scatenare lo shutdown di una macchina, quando questa risulta inattiva per un po' di tempo (con un po' di tempo intendo un periodo di tempo variabile da VM a VM), ma con scarso risultato. La maggior parte delle utility infatti controllano tastiera e/o mouse, ma questo non va sempre bene, perchè in alcuni casi ci si collega via TS e non ci si trova fisicamente davanti al PC in questione. Venerdì mattina, quasi per caso, ci siamo ritrovati davanti alla macchina del caffè ed abbiamo discusso di questo problema. Mi sono quindi offerto volontario per dare una mano, sviluppando un'applicazione managed capace di monitorare il periodo di idle del sistema (occupazione della CPU) e di spegnere la VM quando necessario.

Performance Counter
Ho utilizzato un Performance Counter (PC) per attivare il monitoraggio dell'occupazione della CPU.

PerformanceCounter cpu;
cpu = 
new PerformanceCounter();
cpu.CategoryName = "Processor";
cpu.CounterName = "% Processor Time";
cpu.InstanceName = "_Total";

Inizialmente avevo sviluppato un'applicazione Windows Forms, per una mia predisposizione naturale, poi sono passato alla creazione di un Windows Service che è più consono allo scopo preposto. Comunque sia, ho utilizzato un System.Timers.Timer per ottenere ad intervalli regolari il valore del PC:

float value = cpu.NextValue();

Non voglio illustrarvi la logica in base alla quale scateno lo shutdown, perchè è talmente particolare e ben congegnata che la considero mia proprietà intellettuale, insieme alle persone con le quali l'ho studiata. Vi basti sapere che lo shutdown avviene ovviamente dopo un certo periodo di tempo nel quale la CPU rimane al di sotto di una certa soglia (ma ci sono di mezzo comunque altre logiche).

Grazie ad una classe che viene serializzata/deserializzata su un file XML, salvo e carico i parametri in base ai quali il servizio decide come comportarsi. Questo mi permette di decidere, ad esempio, qual'è il valore di soglia della CPU (per determinare quando considerare una certa VM come inattiva), l'intervallo di campionamento, se avere il log attivo o meno, etc. etc. Il log viene scritto fra i log di sistema attraverso il componente EventLog trascinato banalmente sul designer del servizio stesso: dal momento che gli utenti di tale servizio saranno sistemisti, è molto più semplice metterli in condizione di usare uno strumento come l'Event Viewer che conoscono alla perfezione, piuttosto che inventarsi qualcosa da zero di sana pianta.

Windows Service e le Exception non gestite
Questa mattina ho creato il mio primo Windows Service davvero utile a qualcuno.  Non ho trovato grandi difficoltà, è sufficiente sfruttare il template del progetto disponibile in VS2005 e fare l'override dei metodi:

protected override void OnStart(string[] args)
{ }
protected override void OnStop()
{ }

La cosa comoda è che possiamo eventualmente sostituire in tempo reale il file EXE appartenente al servizio, prelevandolo dalla directory dove è stato appena compilato e copiandolo nella directory dove il servizio è stato installato. Ovviamente, è necessario che il servizio sia stoppato, altrimenti il file EXE risulta in uso.

Se posso darvi un consiglio, gestite tutti gli errori nello Start e nello Stop, perchè se vi scappa una Exception non gestita non riuscirete più ad avviare il servizio o a stopparlo. Quest'ultimo caso è un po' più grave, perchè non riuscirete più a sostituire l'eseguibile e dovrete per forza riavviare il PC (se il servizio è impostato come avvio manuale).

E fare fare lo shutdown?
Per spegnere la VM, ho utilizzato questa classe WindowsController, scaricabile liberamente da qui. Questa classe dispone di un set di metodi statici che, sfruttando P/Invoke, danno la possibilità di fare una cosa tipo questa:

WindowsController.ExitWindows(RestartOptions.PowerOff, true);

Da notare che RestartOptions è una Enum che contiene le seguenti voci:

public enum RestartOptions
{
    LogOff = 0,
    PowerOff = 8,
    Reboot = 2,
    ShutDown = 1,
    Suspend = -1,
    Hibernate = -2
}

Il Tech-Team è davvero contento, adesso. Hanno girovagato per la Rete senza bussola, senza sapere che la soluzione era a portata di mano, bisognava soltanto raggiungerla!

powered by IMHO 1.2

Print | posted on lunedì 31 luglio 2006 17:59 | Filed Under [ Sviluppo .NET ]

Feedback

Gravatar

# Sono un servizio che dipende dall'Event Log, ricordatelo!

05/09/2006 17:46 | Technology Experience
Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET