Qual é a maneira mais eficiente de registrar erros de script do shell crontab com o tempo de erro?

2

Uma maneira comum de registrar os erros da tarefa crontab é a seguinte:

1 */8 * * * sh /pseudo_path/test.sh 2>> my_err_log 

É um comando conciso, mas não pode registrar o erro e o caminho do arquivo de script é omitido.

Então eu escrevi uma função de registro de erros:

PROGNAME=$(readlink -f "$0")
SCRIPT_ERR_LOG_PATH="/pseudo_path/script_err_log"

error_exit()
{
    timestamp="$(date +%Y%m%d-%H:%M:%S)"
    x_info=$(echo "Error_${PROGNAME}:Line_${1:-"null"}_")
    zeta=$x_info$timestamp
    echo "$zeta" >> $SCRIPT_ERR_LOG_PATH
    exit 1
}

Esta função pode registrar o tempo de erro juntamente com o caminho absoluto do script.
Mas o defeito é, eu tenho que adicionar || error_exit $LINENO em cada linha do meu script para fazer o trabalho. Embora com a substituição em massa do vim, poderia ser muito mais fácil, mas ainda parece uma solução desajeitada.

Existe uma maneira mais inteligente de realizar a mesma tarefa?

    
por Zen 30.07.2015 / 06:46

2 respostas

3

Dependendo da quantidade de informações de registro que você espera produzir, pode valer a pena usar a ferramenta padrão logger para gravá-la no syslog do usuário em /var/log :

1 */8 * * * /path/to/myprog 2>&1 | logger -p user.debug -t 'myprog'

Aqui está um exemplo da saída escrita para /var/log/debug em meu sistema baseado em Debian:

Jul 31 00:17:09 myserver myprog: test message with user.debug

Existem vários pares de instalações / níveis disponíveis para uso. Você pode considerar user.notice ou user.info ou user.debug . Esteja ciente de que alguns deles também podem ser gravados em /var/log/messages e /var/log/syslog .

Se você quiser diferenciar stdout e stderr no seu trabalho cron , enviando apenas stderr para o logger , você pode use um constructo como este, que tenho certeza que os outros irão melhorar:

1 */8 * * * ( /path/to/myprog 2>&1 1>&3 | logger -p user.debug -t 'myprog' ) 3>&1
    
por 31.07.2015 / 01:21
4

Parece-me que você está criando um script Bash, então aproveite o trap builtin do Bash. Por exemplo:

#!/bin/bash
# vim: ft=sh:tw=75:fo-=t:fo+=rcq:ai:

function error_trap()
{
    local -ir __exit_code__=${1:-$?}
    local __timestamp__

    # Reset the ERR sigspec to its original disposition.
    trap - ERR

    __timestamp__=$( date --rfc-3339=seconds --date=now )

    # Hint...
    #declare -p BASH_LINENO
    #declare -p BASH_COMMAND

    echo "[${__timestamp__}] (Line: ${BASH_LINENO[0]}) :: ERROR :: ${BASH_COMMAND}" >&2

    exit ${__exit_code__}
}

# Register function 'error_trap' as the trap handler for
# the ERR (error) sigspec.
trap "{ error_trap; }" ERR

# Try it out; deliberately crash-and-burn this script.
ls this-does-not-exist

Aqui está a saída que vejo quando invoco este script:

ls: cannot access this-does-not-exist: No such file or directory
[2015-07-30 01:36:32-05:00] (Line: 24) :: ERROR :: ls this-does-not-exist
    
por 30.07.2015 / 08:52