feedburner

Lorem ipsum dolor sit amet,
consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore
et dolore magna aliqua.

Mostrando entradas con la etiqueta Linux tips. Mostrar todas las entradas
Mostrando entradas con la etiqueta Linux tips. Mostrar todas las entradas

Script para grabar lo que se hace en un shell ( ssh )

Etiquetas:

Por mi trabajo debo documentar las acciones que ejecuto en los hosts de los clientes con total fidelidad. Hace un tiempo estuve buscando alguna herramienta tipo gnome-terminal ( o consola virtual ) con la posibilidad de guardar el log de toda la entrada/salida que realizara dentro de dicha terminal. Esta funcionalidad me sería muy útil no tan solo para poder realizar la documentación que quiero ofrecer, sino también para poder disponer de forma rápida de ejemplos prácticos de ejecución de comandos vía terminal o como log de algún conjunto de acciones particulares. De momento no he encontrado ningún terminal con esa funcionalidad ( tampoco he hecho una búsqueda exahustiva ) pero si que encontré la aplicación propia de bash script que permite hacer algo parecido. Mediante un shell que he montado, automáticamente se graba toda la entrada/salida de lo que ejecuto a través de un ssh, guardándome el log en un directorio predeterminado y organizado por hosts accedidos. El nombre del fichero de log me indica con que usuario realicé el ssh y en que momento. Os dejo aquí el script ( en mis ejemplos se llama fer_ssh2.sh ) por si os es útil o por si os lo puede ser con las modificaciones que creáis oportunas. También adjunto un ejemplo de salida de ejecuciones así como el aspecto del directorio de log para que sirva de ejemplo de lo que he contado.


#!/bin/bash
CADENA=$1
DIRBASE=$HOME/logs_ssh2
FECHA=`date +%Y%m%d-%H.%M.%S`
ELHOST=${CADENA#*@}
ELUSER=${CADENA%@*}
DIRLOG=$DIRBASE/$ELHOST
if [ -d $DIRLOG ]; then
# si existe no hacemos nada - TODO: mirar si podemos negar el if
echo "1" > /dev/null
#el directorio existe, seguimos
else
mkdir -p $DIRLOG
fi
LOG=$DIRLOG/$FECHA-$ELUSER.log
echo "**************************************************"
echo "* HACIENDO SSH CONTRA $1"
echo "* Guardando log en $LOG"
echo "**************************************************"
script -c "ssh -X $1" $LOG
exit


  • Salida real del terminal donde lanzo fer_ssh2.sh ( contra mi propio host vía nombre máquina )


dballester@nebuchadnezzar:~$ fer_ssh2.sh dballester@nebuchadnezzar
**************************************************
* HACIENDO SSH CONTRA dballester@nebuchadnezzar
* Guardando log en /home/dballester/logs_ssh2/nebuchadnezzar/20071220-12.19.26-dballester.log
**************************************************
Script iniciado; el fichero es /home/dballester/logs_ssh2/nebuchadnezzar/20071220-12.19.26-dballester.log
The authenticity of host 'nebuchadnezzar (127.0.1.1)' can't be established.
RSA key fingerprint is af:6e:94:98:83:e1:d3:22:a9:c2:cf:d7:28:3a:59:c3.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'nebuchadnezzar' (RSA) to the list of known hosts.
dballester@nebuchadnezzar's password:
Linux nebuchadnezzar 2.6.22-14-generic #1 SMP Sun Oct 14 23:05:12 GMT 2007 i686

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.
You have mail.
Last login: Thu Dec 20 11:59:12 2007 from localhost
dballester@nebuchadnezzar:~$ hostname
nebuchadnezzar
dballester@nebuchadnezzar:~$ df -h
S.ficheros Tamaño Usado Disp Uso% Montado en
/dev/sda6 4,6G 3,9G 536M 88% /
varrun 502M 112K 502M 1% /var/run
varlock 502M 0 502M 0% /var/lock
udev 502M 108K 502M 1% /dev
devshm 502M 0 502M 0% /dev/shm
lrm 502M 34M 468M 7% /lib/modules/2.6.22-14-generic/volatile
/dev/mapper/data-homes
30G 16G 13G 56% /home
/dev/sda1 76M 41M 32M 57% /boot
/dev/mapper/data-oracle11g
7,9G 5,9G 1,6G 79% /u01
/dev/scd0 7,6G 7,6G 0 100% /media/cdrom0
dballester@nebuchadnezzar:~$ exit
logout
Connection to nebuchadnezzar closed.
Script terminado; el fichero es /home/dballester/logs_ssh2/nebuchadnezzar/20071220-12.19.26-dballester.log
dballester@nebuchadnezzar:~$



  • Salida real del terminal donde lanzo fer_ssh2.sh ( contra mi propio host vía localhost )

dballester@nebuchadnezzar:~$ fer_ssh2.sh dballester@localhost
**************************************************
* HACIENDO SSH CONTRA dballester@localhost
* Guardando log en /home/dballester/logs_ssh2/localhost/20071220-12.21.35-dballester.log
**************************************************
Script iniciado; el fichero es /home/dballester/logs_ssh2/localhost/20071220-12.21.35-dballester.log
dballester@localhost's password:
Linux nebuchadnezzar 2.6.22-14-generic #1 SMP Sun Oct 14 23:05:12 GMT 2007 i686

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.
You have mail.
Last login: Thu Dec 20 12:19:33 2007 from nebuchadnezzar
dballester@nebuchadnezzar:~$ ifconfig | grep -A2 Ether
eth0 Link encap:Ethernet HWaddr 00:14:22:A2:5E:86
inet addr:172.31.152.20 Bcast:172.31.152.255 Mask:255.255.255.0
inet6 addr: fe80::214:22ff:fea2:5e86/64 Scope:Link
dballester@nebuchadnezzar:~$ mii-tool
SIOCGMIIPHY on 'eth0' failed: Operation not permitted
SIOCGMIIPHY on 'eth1' failed: Operation not permitted
SIOCGMIIPHY on 'eth2' failed: Operation not permitted
SIOCGMIIPHY on 'eth3' failed: Operation not permitted
SIOCGMIIPHY on 'eth4' failed: Operation not permitted
SIOCGMIIPHY on 'eth5' failed: Operation not permitted
SIOCGMIIPHY on 'eth6' failed: Operation not permitted
SIOCGMIIPHY on 'eth7' failed: Operation not permitted
no MII interfaces found
dballester@nebuchadnezzar:~$ sudo mii-tool
[sudo] password for dballester:
eth0: no autonegotiation, 10baseT-HD, link ok
SIOCGMIIPHY on 'eth1' failed: Operation not supported
dballester@nebuchadnezzar:~$




  • Aspecto de los directorios de log

dballester@nebuchadnezzar:~$ ls -lR logs_ssh2
logs_ssh2:
total 36
drwxr-xr-x 2 dballester dballester 4096 2007-12-20 12:23 localhost
drwxr-xr-x 2 dballester dballester 4096 2007-12-20 12:19 nebuchadnezzar

logs_ssh2/localhost:
total 16
-rw-r--r-- 1 dballester dballester 4096 2007-12-20 12:22 20071220-12.21.35-dballester.log
-rw-r--r-- 1 dballester dballester 131 2007-12-20 12:23 20071220-12.23.10-dballester.log

logs_ssh2/nebuchadnezzar:
total 4
-rw-r--r-- 1 dballester dballester 1795 2007-12-20 12:19 20071220-12.19.26-dballester.log
dballester@nebuchadnezzar:~$

The power of time

Etiquetas:

La instrucción time, usada tal cual, devuelve estadísticas de tiempo invertido en la ejecución del comando que se pase por parámetro. Según man time :

"(...)
La orden time ejecuta el programa orden con los argumentos suministra
dos. Cuando orden finaliza, time escribe un mensaje en la salida
estándar devolviendo estadísticas temporales sobre la ejecución de
este programa. Estas estadísticas están compuestas por (i) el tiempo
real transcurrido entre la llamada y la finalización de orden , (ii)
el tiempo de usuario del procesador (la suma de los valores tms_utime y
tms_cutime en un struct tms tal y como devuelve times(2)), y (iii) el
tiempo de sistema del procesador (la suma de los valores tms_stime y
tms_cstime en un struct tms tal y como devuelve times(2)).
(...)"


Veámos un ejemplo:

dballester@nebuchadnezzar:~$ time scp sqldeveloper-1.1.2.2579-no-jre.zip dballester@localhost:/tmp/prueba2.zip
dballester@localhost's password:
sqldeveloper-1.1.2.2579-no-jre.zip 100% 39MB 38.8MB/s 00:01

real 0m4.963s
user 0m0.688s
sys 0m0.104s
dballester@nebuchadnezzar:~$

Ok, pero si seguimos leyendo el man de time, éste es capaz de darnos muchísima más información. Lo que vemos de real, user y sys es tan solo la salida por defecto y la punta del iceberg.

time nos puede dar estadísticas de ( entre otras ) : el número de veces que el proceso ha sido sacado de la memoria principal, el número de veces que el sistema ha sacado al proceso de ejecución en CPU por haber consumido todo el tiempo asignado para él, número de mensajes ( sockets ) enviados y recibidos...

Todas estas estadísticas ( ver man time ) se pueden obtener indicando un formato de salida determinado a time. Como yo soy, entre muchas otras cosas, vago y con falta de memoria, he montado un script que visualiza todas las estadísticas. No hay magia, solo las muestro pero agrupadas por área. Os dejo el código junto con un ejemplo de ejecución. Para los que nos dedicamos a la consultoría creo que nos irá muy bien tener este script a mano. Está bajo licencia GPL2 así que ya sabéis podéis usarlo, transformarlo y distribuirlo bajo los límites de dicha licencia.

Script time_command.sh disponible en in.solit.us http://in.solit.us/archives/download/23169



Una vez bajado nuestra máquina, hay que darle derechos de ejecucción

chmod 755 time_command.sh


Ejemplo de lanzamiento

Acepta 2 parámetros, el primero debe ser el comando a ejecutar, limitado entre comillas dobles. El segundo es el fichero de log donde se guarda la salida de las estadísticas. Este segundo parámetro es opcional y si no se informa el script generará uno que creará con los datos de la fecha ( fecha/hora hasta los segundos ) del momento de la ejecución, y lo dejará en el mismo directorio donde se ha lanzado el script ( por lo tanto debemos tener derechos de escritura en dicho directorio). Yo recomiendo que dejéis este script en vuestro home y lo lancéis desde ahí


$ ./time_command.sh "scp sqldeveloper-1.1.2.2579-no-jre.zip dballester@localhost:/tmp/prueba2.zip" cp2.log
The authenticity of host 'localhost (127.0.0.1)' can't be established.
RSA key fingerprint is 43:53:7e:71:3a:95:ff:b4:d1:2d:21:dc:c4:1b:ad:1d.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'localhost' (RSA) to the list of known hosts.
dballester@localhost's password:
sqldeveloper-1.1.2.2579-no-jre.zip


Log resultante

$ cat cp2.log
Comand executed scp sqldeveloper-1.1.2.2579-no-jre.zip dballester@localhost:/tmp/prueba2.zip
TIME COMMAND

Elapsed real (wall clock) time used by the process, in [hours:]minutes:seconds 0:06.91
Elapsed real (wall clock) time used by the process in seconds 6.91


CPU STASTISTICS

Percentage of the CPU that this job got(1) 13%
Total number of CPU-seconds used by the system on behalf of the process (in kernel mode), in seconds 0.11
Total number of CPU-seconds that the process used directly (in user mode), in seconds 0.82
Number of times that the program was context-switched voluntarily(2) 5437
Number of times the process was context-switched involuntarily (because the time slice expired) 6024
Number of signals delivered to the process 0


MEMORY STATISTICS

Average amount of shared text in the process, in Kilobytes 0
Average size of the process’s unshared data area, in Kilobytes 0
Average unshared stack size of the process in Kilobytes 0
Average total (data+stack+text) memory use of the process, in Kilobytes 0
Maximum resident set size of the process during its lifetime, in Kilobytes 0
Average resident set size of the process in Kilobytes 0
Number of minor, or recoverable, page faults(3) 1031
Number of times the process was swapped out of main memory 0
System’s page size in bytes(4) 4096


I/O STATISTICS

Number of file system inputs by the process 0
Number of file system outputs by the process 0
Number of major, or I/O-requiring, page faults that occurred while the process was running(5) 1
Number of socket messages received by the process 0
Number of socket messages sent by the process 0




(1) This is just user + system times divided by the total running time
(2) For instance while waiting for an I/O operation to complete
(3)These are pages that are not valid (so they fault)
but which have not yet been claimed by other virtual pages.
Thus the data in the page is still valid but the system tables must be updated.
(4) This is a per-system constant, but varies between systems.
(5) These are faults where the page has actually migrated out of primary memory.












Instrucción watch

Etiquetas:

Cuando montamos un sistema de alta disponibilidad siempre hay que utilizar redundancia para evitar los SPOF ( single Point Of Failure ) o dicho de otra manera: Si quieres alta disponibilidad necesitas tenerlo todo como mínimo 2 veces porque de los elementos vitales para el servicio ( tarjeta de red, discos, controladora, arquitectura fiber channel, electricidad... ) si solo dispones de uno solo, como ese elemento sufra una caída adiós disponibilidad y adiós servicio.

¿A que viene esto? pues bien, viene a que cuando montamos un sistema de alta disponibilidad antes de entregárselo al cliente hemos de verificar que los elementos redundantes que hemos aplicado funcionan correctamente y el servicio no se pierde en caso de fallo de uno de esos elementos. Para certificar el correcto funcionamiento siempre ejecutamos procedimientos que implican un corte 'a la brava' de todos los SPOF protegidos. Es decir, teniendo el cluster arrancado y dando servicio desconectamos cables de red , certificamos que el sistema es consciente de la falta de ese elemento pero que no se ve afectado, volvemos a conectar el cable y certificamos que todo está OK, ya que tan importante es sobrevivir a la caída de un elemento de un cluster como a la consiguiente recuperación y reuso de dicho elemento una vez se ha solventado la incidencia. Lo mismo hacemos con los discos, las conexiones de fibra óptica...

Cuando hago estos tests necesito una herramienta que me visualice de forma efectiva y rápida los cambios de estado de los distintos elementos. Por ejemplo, para saber el estado del link ( quitar y poner cables ) de las tarjetas de red puedo ejecutar mii-tool

root@nclserver02:~# mii-tool
eth0: negotiated 100baseTx-FD, link ok
eth1: negotiated 100baseTx-FD, link ok
root@nclserver02:~#


Que me indica que en ese momento las 2 tarjetas físicas de red están conectadas mediante cable y tienen link ( eth1: negotiated 100baseTx-FD, link ok )

En caso de quitar uno de los cables, si vuelvo a ejecutar mii-tool me aparece el cambio de estado


root@nclserver02:~# mii-tool
eth0: negotiated 100baseTx-FD, link ok
eth1: no link
root@nclserver02:~#


pero me iría mucho mejor ejecutarlo una vez y poder ver en pantalla el cambio sin tener que volver a ejecutar la instrucción. Esto es aplicable también al estado de los filesystems ( df -k ) , multipath... en fin, que preferiría que en según que casos no tener que ir ejecutando periódicamente la instrucción que me permita ver el cambio.

Para eso utilizo la aplicación watch, que viene de serie en todas las distribuciones que he usado y que francamente me parece de una gran utilidad, todo y que hasta ahora en ninguno de los clientes con los que he trabajado la conocían. Es por esto que dejo esta entrada, para dar a conocer que es esta aplicación y como se usa. Estoy seguro que una vez la empieces a usar se convertirá en una de tus herramientas imprescindibles ;)

Tal y como reza man watch, watch ejecuta periódicamente una instrucción visualizando el resultado en pantalla. Con el ejemplo anterior de mii-tool puedo ejecutar

[root@nclserver03 ~]# watch -n0,5 mii-tool


y cada medio segundo ( -n 0,5 ) watch ejecutará mii-tool y me mostrará el resultado 'full screen' con lo que cada ejecución se solapará encima de la anterior, sin reubicación del contenido. Si necesito hacer un grep para que me muestre solo datos relevantes ( imaginad un ls -l , un cat, etc... podemos entrecomillar ( con la tecla para obtener acentos 'ó' pero sin la 'o', no con la comilla simple " '" ) las sentencias para que watch lo ejecute como un todo, de otra forma las instrucciones posteriores a una tubería ( | ) se aplicarán a la ejecución de watch en sí, no a lo que tiene que ejecutar watch. Por ejemplo si quiero ver como se va llenando el filesystem /dev/sda3 podría ejecutar

root@nclserver02:~# watch -n0,5 'df -k | grep "/dev/sda3"'



Otros parámetros interesantes y no excluyente de watch son

-d pone en video inverso los cambios entre 2 tomas

-t no muestra una cabecera que pone por defecto con información sobre la instrucción que se está ejecutando, el periodo de ejecución y la fecha / hora


Fuentes: watch --help