I see dark around me
Blue skies turn black into the gloom
Your eyes shining through the night
Angel tears, and demon love
Living on, long before the sunrise
Getting lost in a world of fantasies
Until the morning bright light
steals away all our fancy dreams
Sometimes I feel that I'm going nowhere
Waiting for something I can never have
Lost in time, can you feel my heart beating
How will it go? I can barely see my way
I don't know how to escape from here
A cold wind blows down the avenue
But don't mind, we will find our way
A way out to be pleased again
Lasting sorrow, don't look back and wonder
Keep on moving, dancing all night long
And still I can't forget the words you said
Whispers in my ears
Sometimes I feel that I'm going nowhere
Searching for something I can never have
Lost in time, can you feel my heart beating
How will it go? I can barely see my way
What should we do to live on?
What should we do, just killing time?
What should we do to raise our heads?
What should we do just to survive?
I've seen the end, I can't hold on
Can't find my way back anymore
And silver light still shines so bright
And shines so deep inside my eyes
1 nov 2010
27 ott 2010
Process Killer
Quando un programma va in crash la colpa viene attribuita sempre al programmatore. Mentre quando un programma si blocca, o è troppo lento, è di certo per qualche misfatto dell'amministratore di sistema. Anche se magari il programma è scritto con i piedi ed è propenso all'inchiappettamento di tutti i server su cui gira.
Per ristabilire un po' di giustizia divina, ho pensato di killare senza pietà tutti i processi che utilizzano ferocemente la CPU per più di un determinato tempo. Metodo barbaro, ma molto in voga negli Unix dei vecchi tempi... e non solo.
Naturalmente nel mio caso si tratta di processi che dovrebbero essere molto leggeri ma per qualche strana ragione si incastrano e finiscono per utilizzare il processore a pieno regime, infastidendo anche tutti gli utenti di programmi buoni e gentili.
Come punto di partenza, direi di dare un'occhiata all'output del comando pslist, che lista tutti i processi in esecuzione su di una macchina (locale o remota, a patto di avere i privilegi necessari):
le cui colonne interessanti sono le prime due (nome del process e PID) e le ultime due:
Elapsed Time: tempo totale di esecuzione del processo
CPU Time: tempo effettivamente utilizzato dal processo
ad esempio explorer è in esecuzione da 28 ore e 41 minuti, e durante questo periodo ha utilizzato la cpu per 7 minuti e 39 secondi. Proviamo a rilanciare il psexec e a vedere che cosa succede:
il comando è stato lanciato circa 30 secondi dopo il primo, ed infatti tutto gli Elapsed Time sono aumentati circa di 30 secondi, processo PsList escluso ma se osserviamo bene si tratta di un nuovo processo con un nuovo PID.
Anche la colonna CPU Time è variata per alcuni processi, e se dividiamo il delta del CPU Time per il delta dell'Elapsed Time possiamo ottenere... la percentuale di utilizzo del processore di questo processo relativamente la periodo di tempo intercorso tra i due lanci del comando psexec.
Da notare che se la macchina dispone di più processori nel Task Manager di Windows vedremo la percentuale riferita a tutte le CPU: un processo che gira su di un singolo processore non potrà quindi superare il 25% di CPU se la macchina dispone di 4 processori.
Con il comando psexec invece non ci dobbiamo preoccupare del numero di processori che ha la macchina: il tempo di CPU utilizzato diviso il tempo di CPU avuto è disposizione può variare da zero a uno ed è l'utilizzo effettivo del signolo processore.
Ho scritto questo codice in Python che controlla ad intervalli regolari un elenco di server, e che giustizia tutti i processi che durante questo periodo di tempo hanno consumato più del 90% della propria CPU:
da sistemare per bene... e da usare con opportuna cautela!
Per ristabilire un po' di giustizia divina, ho pensato di killare senza pietà tutti i processi che utilizzano ferocemente la CPU per più di un determinato tempo. Metodo barbaro, ma molto in voga negli Unix dei vecchi tempi... e non solo.
Naturalmente nel mio caso si tratta di processi che dovrebbero essere molto leggeri ma per qualche strana ragione si incastrano e finiscono per utilizzare il processore a pieno regime, infastidendo anche tutti gli utenti di programmi buoni e gentili.
Come punto di partenza, direi di dare un'occhiata all'output del comando pslist, che lista tutti i processi in esecuzione su di una macchina (locale o remota, a patto di avere i privilegi necessari):
pslist v1.29 - Sysinternals PsList Copyright (C) 2000-2009 Mark Russinovich Sysinternals Process information for ER-MEJO: Name Pid Pri Thd Hnd Priv CPU Time Elapsed Time Idle 0 0 2 0 0 23:05:50.623 0:00:00.000 System 4 8 114 4338 52 0:11:32.114 28:42:03.487 smss 252 11 3 30 340 0:00:00.171 28:42:03.487 csrss 348 13 9 1033 2744 0:00:06.645 28:41:51.132 wininit 416 13 3 79 992 0:00:00.093 28:41:50.414 explorer 4448 8 36 1252 69768 0:07:39.797 28:41:04.882 iexplore 3772 8 13 382 7172 0:00:04.539 3:14:05.766 iexplore 5788 8 22 704 97632 0:05:51.345 3:14:02.648 PsList 4136 13 1 151 1980 0:00:00.187 0:00:00.172
le cui colonne interessanti sono le prime due (nome del process e PID) e le ultime due:
Elapsed Time: tempo totale di esecuzione del processo
CPU Time: tempo effettivamente utilizzato dal processo
ad esempio explorer è in esecuzione da 28 ore e 41 minuti, e durante questo periodo ha utilizzato la cpu per 7 minuti e 39 secondi. Proviamo a rilanciare il psexec e a vedere che cosa succede:
Name Pid Pri Thd Hnd Priv CPU Time Elapsed Time Idle 0 0 2 0 0 23:06:42.540 0:00:00.000 System 4 8 114 4342 52 0:11:32.426 28:42:33.493 smss 252 11 3 30 340 0:00:00.171 28:42:33.493 csrss 348 13 9 1050 2744 0:00:06.645 28:42:21.138 wininit 416 13 3 79 992 0:00:00.093 28:42:20.420 explorer 4448 8 42 1295 71484 0:07:40.234 28:41:34.888 iexplore 3772 8 13 389 7600 0:00:04.617 3:14:35.772 iexplore 5788 8 23 716 95520 0:05:53.513 3:14:32.654 PsList 1792 13 1 151 1988 0:00:00.171 0:00:00.156
il comando è stato lanciato circa 30 secondi dopo il primo, ed infatti tutto gli Elapsed Time sono aumentati circa di 30 secondi, processo PsList escluso ma se osserviamo bene si tratta di un nuovo processo con un nuovo PID.
Anche la colonna CPU Time è variata per alcuni processi, e se dividiamo il delta del CPU Time per il delta dell'Elapsed Time possiamo ottenere... la percentuale di utilizzo del processore di questo processo relativamente la periodo di tempo intercorso tra i due lanci del comando psexec.
Da notare che se la macchina dispone di più processori nel Task Manager di Windows vedremo la percentuale riferita a tutte le CPU: un processo che gira su di un singolo processore non potrà quindi superare il 25% di CPU se la macchina dispone di 4 processori.
Con il comando psexec invece non ci dobbiamo preoccupare del numero di processori che ha la macchina: il tempo di CPU utilizzato diviso il tempo di CPU avuto è disposizione può variare da zero a uno ed è l'utilizzo effettivo del signolo processore.
Ho scritto questo codice in Python che controlla ad intervalli regolari un elenco di server, e che giustizia tutti i processi che durante questo periodo di tempo hanno consumato più del 90% della propria CPU:
from __future__ import division
import subprocess
import re
import time
word = dict()
pausa = 30
servers = ('citrix01', 'citrix02', 'citrix03', 'server', 'server-2')
def milliSeconds(time):
tm = re.match("(\d*)\:(\d*)\:(\d*)\.(\d*)", time)
if tm:
return long(tm.group(1)) * 60*60*1000 + long(tm.group(2)) * 60*1000 + long(tm.group(3)) * 1000 + long(tm.group(4))
else:
return 0
def getProcess(server, nome):
pslist = subprocess.Popen('"c:\program files\utils\pslist.exe" \\\\' + server + ' ' + nome, shell=False, stdout=subprocess.PIPE)
for line in pslist.stdout:
proc = re.match("^(\w+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+([\w\:\.]+)\s+([\w\:\.]+)", line)
if proc:
serverPid = server + '.' + proc.group(2)
if serverPid in word:
if (milliSeconds(proc.group(7))-milliSeconds(word[serverPid][1]))/(milliSeconds(proc.group(8))-milliSeconds(word[serverPid][2]))>0.90:
subprocess.Popen('"c:\program files\utils\pskill.exe" \\\\' + server + ' ' + word[serverPid][4])
else:
if proc.group(1) <> "Idle" and proc.group(1) <> "System":
word[serverPid] = [proc.group(1), proc.group(7), proc.group(8), server, proc.group(2)]
def main():
while True:
for server in servers:
getProcess(server, 'winword')
time.sleep(pausa)
if __name__ == "__main__":
main()
da sistemare per bene... e da usare con opportuna cautela!
25 ott 2010
QR Code
Bella l'idea di utilizzare codici a barre a due dimensioni, detti Codici QR, per memorizzare vari tipi di informazioni comprese URL:
chissà se in casa Google si stanno attrezzando per interpretare questi codici ed includerli nel PageRank?
E simpatica anche l'idea di Semapedia.org che propone di linkare il mondo fisico a quello virtuale!
Ma... cliccare su link a caso su di un browser non è mai una stata buona idea. Non è che un giorno tutto ciò comporterà qualche problema di sicurezza? O_o
Meglio pensarci per tempo, che non si sa mai!
chissà se in casa Google si stanno attrezzando per interpretare questi codici ed includerli nel PageRank?
E simpatica anche l'idea di Semapedia.org che propone di linkare il mondo fisico a quello virtuale!
Ma... cliccare su link a caso su di un browser non è mai una stata buona idea. Non è che un giorno tutto ciò comporterà qualche problema di sicurezza? O_o
Meglio pensarci per tempo, che non si sa mai!
Dati oggettivi ed interpretazione
Riguardo ai grafici che riportano l'andamento delle temperature della terra e che vengono presentati al grande pubblico, una cosa importante da sapere è che per ottenerli non è sufficiente inserire tutti i dati a disposizione su di un foglio Excel, cliccare su "Inserisci Grafico", e vedere che cosa ne viene fuori.
I grafici che vediamo sono il risultato di anni di analisi e pulizia.
Mi ricordo un fatto curioso e poco conosciuto, e cioè che tutti i grafici delle temperature degli ultimi anni presentavano un rapido aumento intorno alla metà degli anni 40, seguiti da una altrettanto rapida diminuzione.
Questa variazione era insolita, gli scienziati l'hanno considerata come un dato sporco o una anomalia, ed hanno deciso di "eliminarla".
Tutti i grafici ufficiali sono pertanto stati ripuliti e non presentano questo andamento.
Il procedimento seguito dagli scienziati, naturalmente, è corretto: i dati grezzi sono per loro natura pieni di sporchi, errori, rumore... ed il loro compito è di riuscire ad isolare il vero andamento delle temperature escludendo tutte le sporcizie; il picco in questione è stato isolato perché "stonava" e non pareva avere spiegazione logica, tuttavia eliminare dei dati ad intuito, senza sapere bene il perché, è sempre una sconfitta.
Leggevo su Le Scienze di Aprile 2009 un articolo in cui si dava finalmente una spiegazione a questo picco anomalo.
Da una analisi più approfondita si è visto che l'aumento riguardava infatti le temperature dei mari. Durante gli anni della guerra le navi di rilevazione erano soprattutto statunitensi mentre le navi internazionali avevano diminuito le rilevazioni.
Nelle navi internazionali la temperatura delle acque veniva rilevata tramite secchi calati in acqua che si raffreddano se portati in superficie, mentre nelle navi statunitensi si misurava la temperatura dell'acqua di raffreddamento dei motori, che è più calda della vera temperatura del mare.
Le temperature, naturalmente, erano già state corrette per tenere conto di questo fatto, ma dopo questo studio si è visto che la correzione da applicare non era precisa e doveva essere modificata.
Da un lato è stato dimostrato che l'intuizione è stata esatta e che quindi bene avevano fatto gli scienziati ad eliminare questo dato.
Da un altro punto di vista significa che anche la scienza, pur con dati assolutamente oggettivi a disposizione, è sempre e comunque soggetta all'intuito ed all'interpretazione umana.
I grafici che vediamo sono il risultato di anni di analisi e pulizia.
Mi ricordo un fatto curioso e poco conosciuto, e cioè che tutti i grafici delle temperature degli ultimi anni presentavano un rapido aumento intorno alla metà degli anni 40, seguiti da una altrettanto rapida diminuzione.
Questa variazione era insolita, gli scienziati l'hanno considerata come un dato sporco o una anomalia, ed hanno deciso di "eliminarla".
Tutti i grafici ufficiali sono pertanto stati ripuliti e non presentano questo andamento.
Il procedimento seguito dagli scienziati, naturalmente, è corretto: i dati grezzi sono per loro natura pieni di sporchi, errori, rumore... ed il loro compito è di riuscire ad isolare il vero andamento delle temperature escludendo tutte le sporcizie; il picco in questione è stato isolato perché "stonava" e non pareva avere spiegazione logica, tuttavia eliminare dei dati ad intuito, senza sapere bene il perché, è sempre una sconfitta.
Leggevo su Le Scienze di Aprile 2009 un articolo in cui si dava finalmente una spiegazione a questo picco anomalo.
Da una analisi più approfondita si è visto che l'aumento riguardava infatti le temperature dei mari. Durante gli anni della guerra le navi di rilevazione erano soprattutto statunitensi mentre le navi internazionali avevano diminuito le rilevazioni.
Nelle navi internazionali la temperatura delle acque veniva rilevata tramite secchi calati in acqua che si raffreddano se portati in superficie, mentre nelle navi statunitensi si misurava la temperatura dell'acqua di raffreddamento dei motori, che è più calda della vera temperatura del mare.
Le temperature, naturalmente, erano già state corrette per tenere conto di questo fatto, ma dopo questo studio si è visto che la correzione da applicare non era precisa e doveva essere modificata.
Da un lato è stato dimostrato che l'intuizione è stata esatta e che quindi bene avevano fatto gli scienziati ad eliminare questo dato.
Da un altro punto di vista significa che anche la scienza, pur con dati assolutamente oggettivi a disposizione, è sempre e comunque soggetta all'intuito ed all'interpretazione umana.
Scegliere i colori: programmatori e buon gusto!
La scorsa settimana cercavo un paio di mensole colorate da abbinare ad un mobiletto da mettere in sala. Non trovando nulla di interessante ho provato a chiedere un parere ad un dipendente Ikea, il quale mi ha mostrato delle mensole più larghe rispetto al mobiletto, con un altro spessore, e di colore simile ma diverso.
Credo che i programmatori, quando devono scegliere i colori per i propri programmi o per le pagine web, siano come i dipendenti Ikea: completamente privi di ogni buon gusto.
Capita spesso di vedere utilizzate combinazioni estreme di colori: serve un rosso, un verde, od un blu? Niente di più semplice, si sceglie un buon #ff000 per il rosso, un #00ff00 come verde, e per finire un buon blu #0000ff:
ma questi colori sono pesanti, difficili da combinare, ed assolutamente stonati. La prima regola da ricordare è tutte le combinazioni di colori più estreme devono sempre essere evitate!
Molto meglio utilizzare qualche combinazione più leggera, come ad esempio questa con codice #74A697, #FC8626 e #15766F:
Questi colori stancano di meno e si combinano più facilmente. Ma come scegliere una buona palette di colori?
Un grafico probabilmente non ha nemmeno bisogno di porsi questa domanda, ma un trucco che può usare anche un non grafico consiste nello scegliere una foto colorata, ed estrarre da essa una combinazione di colori che ci piace:
prendiamo un po' della cabina telefonica... ed un altro po' del taxi giallo... ecco qui i nostri amici #e02a2f, #f6d06d e #fbab20:
che possono essere combinati in questo modo:
Naturalmente è solo un esempio, ma come punto di partenza va sempre bene.
Poi magari... un giorno lontano... sistemerò anche i colori di questo blog!
Credo che i programmatori, quando devono scegliere i colori per i propri programmi o per le pagine web, siano come i dipendenti Ikea: completamente privi di ogni buon gusto.
Capita spesso di vedere utilizzate combinazioni estreme di colori: serve un rosso, un verde, od un blu? Niente di più semplice, si sceglie un buon #ff000 per il rosso, un #00ff00 come verde, e per finire un buon blu #0000ff:
ma questi colori sono pesanti, difficili da combinare, ed assolutamente stonati. La prima regola da ricordare è tutte le combinazioni di colori più estreme devono sempre essere evitate!
Molto meglio utilizzare qualche combinazione più leggera, come ad esempio questa con codice #74A697, #FC8626 e #15766F:
Questi colori stancano di meno e si combinano più facilmente. Ma come scegliere una buona palette di colori?
Un grafico probabilmente non ha nemmeno bisogno di porsi questa domanda, ma un trucco che può usare anche un non grafico consiste nello scegliere una foto colorata, ed estrarre da essa una combinazione di colori che ci piace:
prendiamo un po' della cabina telefonica... ed un altro po' del taxi giallo... ecco qui i nostri amici #e02a2f, #f6d06d e #fbab20:
che possono essere combinati in questo modo:
| Data | Euribor 1 mese | Euribor 2 mesi | Euribor 3 mesi | Euribor 6 mesi |
|---|---|---|---|---|
| 18 ottobre 2010 | 0,78% | 1,00% | 1,22% | 1,49% |
| 19 ottobre 2010 | 0,79% | 1,01% | 1,23% | 1,50% |
| 20 ottobre 2010 | 0,81% | 1,02% | 1,24% | 1,51% |
| 21 ottobre 2010 | 0,82% | 1,03% | 1,25% | 1,51% |
| 22 ottobre 2010 | 0,82% | 1,03% | 1,25% | 1,52% |
Naturalmente è solo un esempio, ma come punto di partenza va sempre bene.
Poi magari... un giorno lontano... sistemerò anche i colori di questo blog!
Etichette:
web
15 ott 2010
Negare Group Policy ad un utente o gruppo
Applicare una policy di dominio ad un numero ristretto di utenti è molto semplice: nella sezione Security Filtering del tab Scope si seleziona l'elenco dei gruppi a cui tale policy va applicata:
ma per applicare una policy a tutti tranne ad un singolo utente? Gestire il tutto con i gruppi è possibile, ma spesso complicato. Bisogna quindi ricorrere ad un barbatrucco!
Ci spostiamo nel tab Delegation, aggiungiamo l'utente (od il gruppo) da escludere, e nelle proprietà avanzate togliamo i permessi di lettura della policy:
See you soon!
ma per applicare una policy a tutti tranne ad un singolo utente? Gestire il tutto con i gruppi è possibile, ma spesso complicato. Bisogna quindi ricorrere ad un barbatrucco!
Ci spostiamo nel tab Delegation, aggiungiamo l'utente (od il gruppo) da escludere, e nelle proprietà avanzate togliamo i permessi di lettura della policy:
See you soon!
Etichette:
windows
7 set 2010
Crontab condizionale
Ho la necessità di schedulare ad un orario prestabilito un job tramite crontab. All'ora prestabilita vorrei però che venga effettuato un controllo aggiuntivo, come l'esistenza di un file, l'attivazione di un servizio, o altro. Come posso fare?
Il job è inserito nella crontab in questo modo:
il che indica che ogni mattina alle ore 4 verrà eseguito lo script sincronizza_dati.sh. Vorrei però eseguire questo script solamente se il servizio httpd è attivo.
Il mio script sincronizza_dati.sh potrebbe incominciare in questo modo:
e spesso questa è la soluzione migliore (specie se la sincronia per andare a buon fine richiede per davvero che il servizio httpd sia attivo).
Ma se non è questo il caso allora meglio mettere la condizione nel crontab: in questo modo diventa anche più chiaro capire in quali condizioni lo script viene eseguito.
L'unico problema è trovare la sintassi giusta per farci stare tutto il comando su di una sola riga. Ad esempio si può scrivere il comando così:
Magari con l'aiuto di qualche script in perl si può avere una soluzione più pulita (non è bello avere una schifezza di awk sulla tabella crontab) ma... di quello ne parleremo nel prossimo disco!
Il job è inserito nella crontab in questo modo:
0 4 * * * sincronizza_dati.sh
il che indica che ogni mattina alle ore 4 verrà eseguito lo script sincronizza_dati.sh. Vorrei però eseguire questo script solamente se il servizio httpd è attivo.
Il mio script sincronizza_dati.sh potrebbe incominciare in questo modo:
#!/usr/bin/bash
if [ `service httpd status | awk ' { print $3 } '` = "stopped" ]
then
echo "Servizio disattivato! Usciamo!"
exit
fi
echo "Servizio attivato! Procediamo con la sincronizzazione"
e spesso questa è la soluzione migliore (specie se la sincronia per andare a buon fine richiede per davvero che il servizio httpd sia attivo).
Ma se non è questo il caso allora meglio mettere la condizione nel crontab: in questo modo diventa anche più chiaro capire in quali condizioni lo script viene eseguito.
L'unico problema è trovare la sintassi giusta per farci stare tutto il comando su di una sola riga. Ad esempio si può scrivere il comando così:
0 4 * * * if [ `service httpd status | awk ' { print $5 } '` = "running..." ]; then sincronizza_dati.sh; fi
Magari con l'aiuto di qualche script in perl si può avere una soluzione più pulita (non è bello avere una schifezza di awk sulla tabella crontab) ma... di quello ne parleremo nel prossimo disco!
Etichette:
bash
Iscriviti a:
Post (Atom)






