Tag Archives: bash

Mantenimiento diario de Alfresco

Una vez instalado Alfresco, sea el método que sea el que se ha usado para su instalación (bundle, instalador, instalación separada de servidor de aplicaciones más producto, etc.), es necesario realizar una serie de tareas de mantenimiento diarias para no encontrarnos posteriormente con desagradables sorpresas.

El problema más común en este sentido es que se llene alguna de las particiones o discos que se están usando por parte de Alfresco para almacenar ficheros temporales, documentos borrados o logs.

Para ello, se pueden crear una serie de tareas y scripts para tener un mantenimiento automatizado. En mi caso uso un mantenimiento que termina borrando definitivamente ficheros, en otras situaciones es preferible realizar copias antes de estos borrados.

Lo primero que hay que hacer es tener bien colocado el fichero de logs de Alfresco,  para esto, copiamos el fichero log4j.properties como custom-log4j.properties dentro del extension. Por ejemplo:

cp /opt/alfresco/tomcat/webapps/alfresco/WEB-INF/classes/log4j.properties /opt/alfresco/tomcat/shared/classes/alfresco/extension/custom-log4j.properties

Y seguidamente ponemos el directorio correcto donde se almacenarán los logs. En este caso el siguiente valor:

Fichero: custom-log4j.properties

[…]
log4j.appender.File.File=/opt/alfresco/tomcat/logs/alfresco.log
[…]

Ahora los ficheros de logs propios de Alfresco se crearán dentro del directorio apropiado.

Seguidamente, aunque Alfresco ya realiza una rotación de estos logs por fechas, se puede crear un pequeño script para comprimir los ficheros de logs que han sido rotados:

Fichero: cron_gzip_logs.sh

#!/bin/bash
. `dirname “$0″`/config
for i in `ls ${CATALINA_HOME}/logs/alfresco.log.*[!.gz] 2>/dev/null`
do
        gzip $i
done

Además, podemos borrar los ficheros de logs aunque ya hayan sido rotados y comprimidos pero que tengan un número de días y por tanto ya no nos interesen. Para ello he creado el siguiente script:

Fichero: cron_del_logs.sh

#!/bin/bash

. `dirname “$0″`/config
find ${CATALINA_HOME}/logs/alfresco.log.*.gz -mtime +${AFTER_DAYS} -delete 2>/dev/null

También necesitamos borrar ficheros temporales que hayan sido creados hace días y no se hayan eliminado:

Fichero: cron_del_temp.sh

#!/bin/bash
. `dirname “$0″`/config
find ${CATALINA_HOME}/temp -mtime +${AFTER_DAYS_TEMP} -delete 2>/dev/null

En Alfresco, los ficheros/documentos que ya no están en la papelera y han pasado más de 14 días son movidos a un directorio generalmente llamado contentstore.deleted. Este directorio no es borrado nunca por Alfresco por lo que si se realizan muchas modificaciones de documentos y borrados puede llenarse y ocupar mucho espacio. Para solucionar esto he creado el siguiente script:

Fichero: cron_del_deleted.sh
#!/bin/bash
. `dirname “$0″`/config
find ${CONTENTSTORE_DELETED}/* -mtime +${AFTER_DAYS_DELETED} -delete 2>/dev/null

Ahora solo queda crear el fichero de configuración donde se asignan los valores a las variables usadas:

Fichero: config

CATALINA_HOME=/opt/alfresco/tomcat
AFTER_DAYS=30
AFTER_DAYS_DELETED=5
AFTER_DAYS_TEMP=5
CONTENTSTORE_DELETED=/opt/alfresco/alf_data/contentstore.deleted

Y el fichero maestro que llamará a todos los scripts (al que he llamado adt.sh en alusión a Alfresco Daily Tasks) y que servirá para ponerlo en el cron diario:

Fichero: adt.sh
#!/bin/bash
#
# @Author: Fernando Gonzalez
# @Version: 1.0
# @Fecha: 2011
#
UTILS_DIR=/opt/alfresco/utils
${UTILS_DIR}/cron_gzip_logs.sh
${UTILS_DIR}/cron_del_logs.sh
${UTILS_DIR}/cron_del_temp.sh
${UTILS_DIR}/cron_del_deleted.sh

Y hacer el enlace simbólico dentro del directorio /etc/cron.daily o crearlo en la “crontab”:

cd /etc/cron.daily

ln -s /opt/alfresco/utils/adt.sh .

Esto es simplemente un ejemplo de las tareas que hay que hacer después de la instalación de Alfresco para el mantenimiento diario y así evitar problemas futuros.

Otras consideraciones: Dentro de este mantenimiento, recien instalado Alfresco y si estamos ante un sistema en cluster, recomiendo la lectura del siguiente artículo escrito por Toni de la Fuente sobre el sistema de “jobs” de Alfresco: http://blyx.com/2011/07/01/alfresco-scheduled-jobs-tareas-automaticas-de-mantenimiento/

Actualización (23/08/2011).

En el uso de OpenOffice.org, los ficheros temporales se crean por lo general en el directorio temporal del sistema operativo, en la mayor parte de los casos cuando se trata de Linux es en /tmp. El script para borrar los ficheros temporales del usuario que ejecuta Alfresco sería:

Fichero: cron_del_tmp.sh
#!/bin/bash
. `dirname “$0″`/config
find ${TMP}/ -mtime +${AFTER_DAYS_TMP} -uid $UID -delete 2>/dev/null

Hay que añadir al fichero config las dos líneas de variables usadas:
Fichero: config
[…]
AFTER_DAYS_TMP=5
TMP=/tmp

Y también la ejecución del nuevo script al fichero adt.sh:
[…]
${UTILS_DIR}/cron_del_tmp.sh

Es MUY IMPORTANTE que Alfresco siempre sea ejecutado por un usuario no root ya que de lo contrario si ocurre algún problema en el borrado de ficheros podría desestabilizarse e incluso romperse el sistema.

Calculando métricas en Alfresco mediante scripts

Para el cálculo de métricas en las búsquedas, subidas de ficheros, etc. podemos usar alguno de los programas que existen para estas tareas como es JMeter.

JMeter es un programa en Java, del proyecto Apache, que permite testear aplicaciones web. Es una aplicación de escritorio y muy usada en los entornos en los que se utilizan servidores de aplicaciones, sobre todo Tomcat.

Para más información podemos ir a la URL del proyecto: http://jakarta.apache.org/jmeter/

Si no tenemos tiempo de crear una batería de pruebas siempre podemos recurrir al intérprete BASH de Linux, Unix, MacOS, etc. que puede facilitarnos esta tarea.

Haciendo uso de algún WebScript ya implementado en Alfresco o modificando alguno de estos podemos usar las funciones y comandos de BASH para tomar tiempos.

Búsqueda aleatoria:

Una de las pruebas más importantes es el de las búsquedas en Alfresco. En este caso vamos a usar un WebScript de la parte OpenSearch que tiene Alfresco. El problema de este sistema es que solo devuelve los resultados en 3 formatos, HTML, RSS y ATOM, y en nuestro caso necesitamos que los devuelva en formato texto (TEXT) para poder tratarlo. Para esto, solo tenemos que modificar el descriptor para incluir en el contexto la llamada a una plantilla FreeMarker que devuelva texto plano e incluir esta plantilla. Para no “ensuciar” el despliegue lo haremos creando el directorio en alfresco/extension de forma que además podamos conservarlo entre distintas actualizaciones del producto. El sitio para introducir los dos ficheros será: /alfresco/extension/templates/webscripts/org/alfresco/repository/

Los dos ficheros serán los siguientes:

Fichero: keywordsearch.get.desc.xml


  Alfresco Keyword Search (OpenSearch Enabled)
  Execute Keyword Search against Alfresco Repository (Company Home and below)
  /api/search/keyword.html?q={searchTerms}&p={startPage?}&c={count?}&l={language?}
  /search/keyword.html?q={searchTerms}&p={startPage?}&c={count?}&l={language?}
  /api/search/keyword.texp?q={searchTerms}&p={startPage?}&c={count?}&l={language?}
  /search/keyword.text?q={searchTerms}&p={startPage?}&c={count?}&l={language?}
  /api/search/keyword.atom?q={searchTerms}&p={startPage?}&c={count?}&l={language?}
  /search/keyword.atom?q={searchTerms}&p={startPage?}&c={count?}&l={language?}
  /api/search/keyword.rss?q={searchTerms}&p={startPage?}&c={count?}&l={language?}
  /search/keyword.rss?q={searchTerms}&p={startPage?}&c={count?}&l={language?}
  /api/search/keyword.portlet?q={searchTerms}&p={startPage?}&c={count?}&l={language?}
  guest
  required

Fichero: keywordsearch.get.text.ftl 

${row.name}

Una vez introducidos los ficheros en el sitio correspondiente solo queda ir a la URL http://servidoralfresco:8080/alfresco/service/index y pulsar el botón de refresco de los WebScripts.

Ahora podemos ejecutar el script creado para las búsquedas. Este script lo que hace es una búsqueda por una palabra o KEYWORD, guardar los resultados en un fichero y después realizar el número de búsquedas solicitadas de forma automática guardando los tiempo y redirigiéndolos a un fichero para poder editar  posteriormente los resultados.

La sintaxis del script es:

./random_search usuario password keyword núm_iteracciones url_alfresco

Fichero: random_search

#!/bin/bash

# Pruebas de busquedas en Alfresco usando el webscript “search”
# www.fegor.com

if [ ! $# -eq 5 ]
then
        echo Sintaxis: random_search user passwd keyword num_randoms alfresco_url
        exit 1
fi

echo Realizando consulta completa…
IFSPREV=$IFS
IFS=$’x0A’$’x0D’
curl –user “$1:$2” “$5/service/api/search/keyword.text?q=$3&p=Company%20Home&c=10000&l=es” > random_search_result.txt

echo Comenzando las busquedas…
LINEAS=`cat random_search_result.txt | wc -l`
echo -e “Results of random_search.sh” > random_search_times.csv SG_FOR_I=`date +%s`
for n in $(seq 1 $4);
do
        RNM=$RANDOM
        let “RNM %= $LINEAS”
        let “RNM += 1”
        KEYWORD=`head -n $RNM random_search_result.txt | tail -1 | tr -d ‘r’`
        NS_CURL_I=`date +%s%N`
        curl –user “$1:$2” “$5/service/api/search/keyword.text?q=${KEYWORD}&p=Company%20Home&c=1&l=es”
        NS_CURL_F=`date +%s%N`
        let TOTAL_NS_CURL=$NS_CURL_F-$NS_CURL_I
        let TOTAL_MS_CURL=TOTAL_NS_CURL/1000000
        echo -e “`date`t$KEYWORDt$TOTAL_NS_CURLt$TOTAL_MS_CURL” >> random_search_times.csv 

done
SG_FOR_F=`date +%s`
let TOTAL_SG_FOR=$SG_FOR_F-$SG_FOR_I
echo -e “rrTotal time” >> random_search_times.csv
echo -e “`date`t$TOTAL_SG_FOR” >> random_search_times.csv
IFS=$IFSPREV

Un ejemplo de ejecución del comando sería:

[root@alfpru1 scripts]# ./random_search admin admin “*ftl” 5 http://192.168.56.1:8080/alfresco
Realizando consulta completa…
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   671    0   671    0     0   7910      0 –:–:– –:–:– –:–:–     0
Comenzando las busquedas…
categorysearch.get.atom.404.ftl
show_audit.ftl
categorysearch.get.atom.ftl
my_docs.ftl
general_example.ftl

Y posteriormente en la hoja de cálculo:

Subidas masivas:

Otra de las pruebas es la de realizar subidas masivas y en profundidad de un número de ficheros y comprobar los tiempos de estas subidas. El script es bastante parecido al anterior y hace uso de un WebScript que también está incluido en Alfresco. En este caso hay que crear un “site” llamado “tests” para poder subir los ficheros a dicho espacio.

Fichero: directory_upload
#!/bin/bash

# Pruebas de subidas en Alfresco usando el webscript “upload”
# www.fegor.com

if [ ! $# -eq 5 ]
then
        echo Sintaxis: directory_upload user passwd path ext alfresco_url
        exit 1
fi

echo “Subiendo…”
IFSPREV=$IFS
IFS=$’x0A’$’x0D’

echo -e “Results of directory_upload.sh” > directory_upload_times.csv
SG_FOR_I=`date +%s`
for f in $(find $3 ( -name *.$4 ));
do
        NS_CURL_I=`date +%s%N`
        curl -k -X POST –user “$1″:”$2″ -F filedata=@$f -F siteid=”tests” -F containerid=”documentLibrary” -F uploaddirectory=”testsDir” -F filename=”`basename $f`” -F contenttype=”`file –brief –mime $f`” “$5/service/api/upload” | grep ‘description’ | cut -d ‘:’ -f 2 | tr -d ‘”‘
        NS_CURL_F=`date +%s%N`
        let TOTAL_NS_CURL=$NS_CURL_F-$NS_CURL_I
        let TOTAL_MS_CURL=TOTAL_NS_CURL/1000000
        echo -e “`date`t$ft$TOTAL_NS_CURLt$TOTAL_MS_CURL” >> directory_upload_times.csv
done
SG_FOR_F=`date +%s`
let TOTAL_SG_FOR=$SG_FOR_F-$SG_FOR_I
echo -e “rrTotal time” >> directory_upload_times.csv
echo -e “`date`t$TOTAL_SG_FOR” >> directory_upload_times.csv
IFS=$IFSPREV

Este script también devuelve un fichero (directory_upload_times.csv) para su edición y estudio mediante cualquier sistema de hoja de cálculo como MS-Excel o OpenOffice.org

Un ejemplo de ejecución podría ser el siguiente:

[root@alfpru1 scripts]# ./directory_upload admin admin AMCM2011/ pdf http://192.168.56.1:8080/alfresco
Subiendo…
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 3252k  100   278  100 3252k    253  2968k  0:00:01  0:00:01 –:–:– 3014k
 File uploaded successfully
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  772k  100   253  100  772k    424  1295k –:–:– –:–:– –:–:– 1435k
 File uploaded successfully
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  311k  100   257  100  311k    414   502k –:–:– –:–:– –:–:–  510k
 File uploaded successfully
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 2485k  100   251  100 2485k    385  3814k –:–:– –:–:– –:–:– 3976k
 File uploaded successfully
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  415k  100   251  100  415k    245   406k  0:00:01  0:00:01 –:–:–  429k
 File uploaded successfully
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  481k  100   255  100  481k    443   836k –:–:– –:–:– –:–:–  859k
 File uploaded successfully
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 2471k  100   249  100 2471k    242  2402k  0:00:01  0:00:01 –:–:– 2444k
 File uploaded successfully

… procesando los datos: