RSS

Librería de logging para shell

04 Feb

Para diversos proyectos he tenido la necesidad de crear una librería de logging para bash.

Para quienes no están muy familiarizados con el tema les platicaré un poco. Una librería de logging nos permite gestionar de una manera sencilla y muy controlada los mensajes de una aplicación.

En español, pensemos en un programa escrito en C que utiliza punteros, no somos muy buenos en ello y estamos teniendo un error de segmentación el cual a veces termina en un lugar a veces termina en otro, en fin uno de esos que hay que andar cazando y nos hacen arrancarnos los cabellos. Comúnmente estaríamos poniendo mensajes en el programa para ir cercando el problema y una vez que lo hemos encontrado retiraríamos estos mensajes para liberar el programa a producción. El problema y lo frustrante sucedería cuando aparezca un nuevo error y nos veamos obligados a poner/quitar los mensajes.

¿Que sucedería si siempre estuvieran ahí los mensajes? Imaginemos que ponemos los mensajes y que estos siempre están ahí pero que el programa (o la librería de logging) es lo suficientemente inteligente para saber que mensajes debe de mostrar dependiendo de si lo están corriendo en producción o en desarrollo. Sería muy práctico.

El concepto es muy sencillo:

  1. Se definen varios niveles de mensajes. Los mensajes críticos están en un extremo de la escala, son mensajes que se deben de mostrar siempre sin importar en que ambiente se encuentre, los mensajes de debug están en el otro extremo y solo deben de ser visibles cuando se esté trabajando en un ambiente de desarrollo o bien uno productivo pero se esté realizando la detección de un caso de error.
  2. Se definen varias funciones para mandar los mensajes según el nivel. Comúnmente siempre lo hacemos con un printf en el caso de C, con la librería de logging tendríamos por ejemplo log_critical, log_debug. Es necesaria una función por cada nivel.
  3. En el programa se debe de inicializar la librería de logging. Esto es como mínimo especificar el nivel de los mensajes que se desean mostrar aunque algunas librerías muy sofisticadas pueden realizar otras tareas.
  4. En el programa se debera de utilizar las funciones de la librería para enviar los mensajes que se desee cuidando de usar el nivel apropiado para el mensaje.

Para muestra les dejo la librería de logging que tengo actualmente para bash. Se encuentra muy básica pero espero poco a poco irla creciendo según las necesidades.

 

#!/bin/bash

#Constantes para imprimir el nivel de log en los mensajes
LOG_DEBUG_MSG_LEVEL=DEBUG
LOG_INFO_MSG_LEVEL=INFO
LOG_WARN_MSG_LEVEL=WARN
LOG_FATAL_MSG_LEVEL=FATAL

#Constantes para los niveles de logging
LOG_LEVEL_DEBUG=1
LOG_LEVEL_INFO=2
LOG_LEVEL_WARN=3
LOG_LEVEL_FATAL=4

#Inicializaciones
LOG_LEVEL=$LOG_LEVEL_INFO

log_log(){
local PARM_NIVEL=”$1″
local PARM_MSG=”$2″

printf “[%-5s] %s\n” “$PARM_NIVEL” “$PARM_MSG”

}

log_debug(){
local PARM_MSG=”$1″

if [ $LOG_LEVEL_DEBUG -ge $LOG_LEVEL ] ; then
log_log “$LOG_DEBUG_MSG_LEVEL” “$PARM_MSG”
fi
}

log_info(){
local PARM_MSG=”$1″

if [ $LOG_LEVEL_INFO -ge $LOG_LEVEL ] ; then
log_log “$LOG_INFO_MSG_LEVEL” “$PARM_MSG”
fi
}

log_warn(){
local PARM_MSG=”$1″

if [ $LOG_LEVEL_WARN -ge $LOG_LEVEL ] ; then
log_log “$LOG_WARN_MSG_LEVEL” “$PARM_MSG”
fi
}

log_fatal(){
local PARM_MSG=”$1″

if [ $LOG_LEVEL_FATAL -ge $LOG_LEVEL ] ; then
log_log “$LOG_FATAL_MSG_LEVEL” “$PARM_MSG”
fi
}

 

El núcleo de la librería es la función log_log, lo único que hace es imprimir formateado el mensaje. Alrededor de ella se cosntruyen 5 funciones que actúan como wrappers(envolventes) que lo que hacen es validar si el mensaje se debe de escribir o se desecha, comparando el nivel de esa función contra la variable $LOG_LEVEL, en caso de imprimirse se llama a la función log_log enviándole el nivel de log que se está procesando para que lo imprima apropiadamente.

Una manera de utilizarla sería la siguiente:


#Importar la libreria de log
source $COMMON_SCRIPTS_DIR/logger.sh

LOG_LEVEL=$LOG_LEVEL_DEBUG
log_info “Hola soy info”
log_debug “Hola soy debug”
log_debug “Hola soy debug!!!”

Primero se “importa” la librería (la línea source), posteriormente se configura el nivel deseado (la asignación a la variable LOG_LEVEL), y finalmente se utiliza (invocación a las funciones log_info y log_debug).

En fin, algo adicional que se le pudiera hacer es:

  • Imprimir el nivel de los mensajes con colores (Rojo para crítico y azul para debug p. ej.,
  • Imprimir la hora del mensaje para tracear el tiempo en que ocurre cada cosa.
  • Hacer que los mensajes persistan enviandolos a un archivo.
  • Enviar mensajes al syslog.

Por el momento es todo, espero les sea de utilidad.

 
Deja un comentario

Publicado por en febrero 4, 2016 en Bash, RaspberryPi, unix

 

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

 
A %d blogueros les gusta esto: