Cómo monitorizar los archivos de registro en macOS con un script Bash personalizado

En el panorama informático actual, monitorizar y gestionar eficazmente los archivos de registro es crucial para mantener el buen estado del sistema y garantizar la seguridad. Tanto si eres un profesional de TI como un proveedor de servicios gestionados (MSP), tener la capacidad de buscar y alertar rápidamente sobre un texto específico dentro de un archivo de registro puede ser una poderosa herramienta en tu arsenal. Este post explorará un script Bash personalizado diseñado para monitorizar los archivos de registro en macOS.

La importancia de monitorizar los archivos de registro

Los archivos de registro son un componente crítico en el funcionamiento y mantenimiento de los sistemas informáticos. Contienen registros de eventos, procesos y errores que se producen en un ordenador o red. Mediante el análisis de los archivos de registro, los profesionales de TI pueden identificar problemas, rastrear la causa raíz de los mismos y garantizar el cumplimiento de los requisitos normativos. Sin embargo, examinar manualmente estos archivos para encontrar información relevante puede llevar mucho tiempo y ser propenso a errores.

Aquí es donde entra en juego la automatización. Automatizar el proceso de monitorizar los archivos de registro y activar alertas cuando se encuentra un texto específico puede ahorrar tiempo y reducir el riesgo de pasar por alto problemas críticos. El script que vamos a comentar es una solución sencilla pero eficaz para conseguirlo en macOS.

El script para monitorizar los archivos de registro

#!/usr/bin/env bash

# Description: Alert when the specified Text is found in a text file.
#
# Release Notes: Initial Release
#   By using this script, you indicate your acceptance of the following legal terms as well as our Terms of Use at https://ninjastage2.wpengine.com/terms-of-use.
#   Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms. 
#   Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party. 
#   Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library or website belonging to or under the control of any other software provider. 
#   Warranty Disclaimer: The script is provided “as is” and “as available”, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations. 
#   Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks. 
#   Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script. 
#   EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA).
#
# Text to trigger on: [Alert]
#
# Below are all the valid parameters for this script.
# Preset Parameter: --file "/opt/MyLogFile.log" --text batman
#   Alerts when the text "batman" is found in the file /opt/MyLogFile.log
#    This is Case Sensitive
#     Example where it will alert: "I am batman!"
#     Example where it will alert: "Iambatman!"
#     Example where it will not alert: "IamBatman!"
#     Example where it will not alert: "I am Batman!"
#
# Preset Parameter: --file "/opt/MyLogFile.log" --text Batman --caseInsensitive true
#   Alerts when the text "Batman" is found in the file /opt/MyLogFile.log, but is case insensitive
#    This is Case Insensitive
#     Example where it will alert: "I am batman!"
#     Example where it will alert: "Iambatman!"
#
# Preset Parameter: --file "/opt/MyLogFile.log" --text Batman --wholeWord true
#   Alerts when the text "Batman" is found in the file /opt/MyLogFile.log, but only if it is a word in a sentence.
#    This is Case Sensitive
#     Example where it will alert: "I am Batman!"
#     Example where it will not alert: "IamBatman!"
#

# Determines whether or not help text is necessary and routes the output to stderr
die() {
    local _ret="${2:-1}"
    test "${_PRINT_HELP:-no}" = yes && print_help >&2
    echo "$1" >&2
    exit "${_ret}"
}

# Function that evaluates whether a value passed to it begins by a character
# that is a short option of an argument the script knows about.
# This is required in order to support getopts-like short options grouping.
begins_with_short_option() {
    local first_option all_short_options='ftiwh'
    first_option="${1:0:1}"
    test "$all_short_options" = "${all_short_options/$first_option/}" && return 1 || return 0
}

# THE DEFAULTS INITIALIZATION - OPTIONALS
_arg_file=
_arg_text=
_arg_caseInsensitive="false"
_arg_wholeWord="false"

# Help text function for when invalid input is encountered
print_help() {
    printf '%s\n' "Alert when the specified Text is found in a text file."
    printf 'Usage: %s [-f|--file [path to file]] [-t|--text [text to search]] [-i|--caseInsensitive <true|false>] [-w|--wholeWord <true|false>] [-h|--help]\n' "$0"
    printf '\t%s\n' "-f, --file: path to a log file"
    printf '\t%s\n' "-t, --text: text to alert when found"
    printf '\t%s\n' "-i, --caseInsensitive: search text with case insensitivity (default: false)"
    printf '\t%s\n' "-w, --wholeWord: search for text as a whole word (default: false)"
    printf '\t%s\n' "-h, --help: Prints help"
}

# Grabbing the parameters and parsing through them.
parse_commandLine() {
    while test $# -gt 0; do
        _key="$1"
        case "$_key" in
        -f | --file)
            test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
            _arg_file="$2"
            shift
            ;;
        --file=*)
            _arg_file="${_key##--file=}"
            ;;
        -f*)
            _arg_file="${_key##-f}"
            ;;
        -t | --text)
            test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
            _arg_text="$2"
            shift
            ;;
        --text=*)
            _arg_text="${_key##--text=}"
            ;;
        -t*)
            _arg_text="${_key##-t}"
            ;;
        -i | --caseInsensitive)
            test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
            _arg_caseInsensitive="$2"
            shift
            ;;
        --caseInsensitive=*)
            _arg_caseInsensitive="${_key##--caseInsensitive=}"
            ;;
        -i*)
            _arg_caseInsensitive="${_key##-i}"
            ;;
        -w | --wholeWord)
            test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
            _arg_wholeWord="$2"
            shift
            ;;
        --wholeWord=*)
            _arg_wholeWord="${_key##--wholeWord=}"
            ;;
        -w*)
            _arg_wholeWord="${_key##-w}"
            ;;
        -h | --help)
            print_help
            exit 0
            ;;
        -h*)
            print_help
            exit 0
            ;;
        *)
            _PRINT_HELP=yes die "FATAL ERROR: Got an unexpected argument '$1'" 1
            ;;
        esac
        shift
    done
}

parse_commandLine "$@"

text=$_arg_text
file=$_arg_file
caseInsensitive=$_arg_caseInsensitive
wholeWord=$_arg_wholeWord

# Check if Script Variables where used and overwrite command line parameters
if [[ -n "${textToMatch}" ]]; then
    text=$textToMatch
fi
if [[ -n "${textFile}" ]]; then
    file=$textFile
fi
if [[ -n "${matchWholeWord}" ]]; then
    wholeWord=$matchWholeWord
fi
if [[ -n "${insensitiveToCase}" ]]; then
    caseInsensitive=$insensitiveToCase
fi

# Check if text is not an empty string
if [[ -z "${text}" ]]; then
    echo "[Error] Text not specified"
    exit 2
fi

# Check if text is not an empty string
if [[ -z "${file}" ]]; then
    echo "[Error] File not specified"
    exit 2
fi

# Does file exit and is readable
if [ -f "${file}" ]; then
    echo "[Info] File \"${file}\" exists"
    if [ -r "${file}" ]; then
        echo "[Info] File \"${file}\" is readable"
    else
        echo "[Error] File \"${file}\" is not readable"
        exit 2
    fi
else
    echo "[Error] File \"${file}\" does not exists"
    exit 2
fi

# Detect
count=0
if [[ "${wholeWord}" == "true" ]]; then
    if [[ "${caseInsensitive}" == "true" ]]; then
        count=$(grep -c -i -n -w "$text" "$file")
    else
        count=$(grep -c -n -w "$text" "$file")
    fi
else
    if [[ "${caseInsensitive}" == "true" ]]; then
        count=$(grep -c -i -n -e "$text" "$file")
    else
        count=$(grep -c -n -e "$text" "$file")
    fi
fi

# Alert
if ((count > 0)); then
    echo "[Alert] Found text in file"
    exit 1
else
    echo "[Info] Not found text in file"
    exit 0
fi

 

Accede a más de 700 scripts en el Dojo de NinjaOne Accede aquí

Entender el script

El script proporcionado es un script Bash diseñado para buscar texto específico dentro de un archivo de registro y activar una alerta si se encuentra ese texto. Permite a los usuarios personalizar los parámetros de búsqueda, por ejemplo, si la búsqueda debe distinguir entre mayúsculas y minúsculas o si debe coincidir sólo con palabras completas. Aquí tienes un desglose detallado de cómo funciona el script.

Inicialización del script

El script comienza definiendo algunas funciones para manejar errores, comprobar argumentos válidos y mostrar información de ayuda. La función die(), por ejemplo, se utiliza para terminar el script y mostrar un mensaje de error si algo va mal. Esta función también imprime el texto de ayuda si se proporciona la opción –help.

Configuración de parámetros por defecto

El script inicializa varios parámetros por defecto:

  • archivo_arg: Almacena la ruta del archivo de registro que se va a buscar.
  • _arg_text: Contiene el texto que se debe buscar en el archivo de registro.
  • _arg_caseInsensitive: Determina si la búsqueda debe distinguir entre mayúsculas y minúsculas.
  • _arg_wholeWord: Especifica si la búsqueda debe coincidir sólo con palabras completas.

Estos parámetros pueden ser modificados por el usuario mediante argumentos de línea de comandos al ejecutar el script.

Análisis sintáctico de los argumentos de la línea de comandos

La función parse_commandLine() es responsable de analizar los argumentos de la línea de comandos pasados al script. Admite varias opciones, como –file para especificar el archivo de registro, –text para definir el texto de búsqueda y –caseInsensitivey –wholeWord para personalizar el comportamiento de la búsqueda.

Si falta algún parámetro requerido, el script saldrá con un mensaje de error. Esto garantiza que el script se ejecute con toda la información necesaria.

Validación de entradas y accesibilidad de archivos

Antes de realizar la búsqueda, el script valida las entradas para asegurarse de que no están vacías y comprueba si el archivo especificado existe y es legible. Si el archivo no existe o no es accesible, el script sale con un mensaje de error, evitando una ejecución innecesaria.

Búsqueda en el archivo de registro

La funcionalidad principal del script reside en su capacidad para buscar en el archivo de registro basándose en los parámetros proporcionados. El script utiliza el comando grep, una potente herramienta de búsqueda de texto en archivos, para realizar la búsqueda. Dependiendo de las opciones seleccionadas, grep buscará el texto con o sin distinción entre mayúsculas y minúsculas, y coincidirá con toda la palabra o con parte de ella.

  • Si –wholeWord está establecido en true, el script añade el indicador -w a grep, asegurando que sólo se encuentren palabras completas.
  • Si –caseInsensitive está establecido en true, el script utiliza el indicador -i para ignorar mayúsculas y minúsculas durante la búsqueda.

Activación de alertas

Una vez finalizada la búsqueda, el script cuenta el número de coincidencias encontradas en el archivo de registro. Si se detecta alguna coincidencia, el script activa una alerta imprimiendo [Alerta] Texto encontrado en el archivo. Si no se encuentra ninguna coincidencia, imprime [Info] Texto no encontrado en el fichero. Este sencillo enfoque garantiza que los usuarios sean informados inmediatamente si el texto que están supervisando aparece en el archivo de registro.

Aplicaciones reales

Imagínate a un profesional de TI que gestiona una granja de servidores en la que es crucial controlar la aparición de mensajes de error específicos en los archivos de registro. Al desplegar este script, puede recibir automáticamente una alerta cada vez que aparezca un código o mensaje de error concreto en los registros, lo que le permite tomar medidas inmediatas. Por ejemplo, si en los registros se encuentra el texto “fallo de disco”, el script puede activar una alerta, lo que permite al equipo informático abordar el problema antes de que se convierta en un fallo crítico del sistema.

Comparación con otros métodos

Aunque este script proporciona una forma sencilla y eficaz de supervisar los archivos de registro, otros métodos pueden lograr resultados similares. Por ejemplo, los sistemas de gestión de registros más avanzados, como Splunk o ELK stack, ofrecen análisis de registros completos, incluida la supervisión en tiempo real, consultas complejas e integraciones con otros sistemas. Sin embargo, estas soluciones suelen requerir más recursos y pueden resultar excesivas para entornos más pequeños o casos de uso específicos en los que basta con un simple script Bash.

Preguntas frecuentes

1. ¿Se puede utilizar este script en sistemas operativos distintos de macOS?

Sí, este script está escrito en Bash, que está disponible en la mayoría de los sistemas operativos tipo Unix, incluido Linux. No obstante, pueden ser necesarios algunos ajustes en función del entorno específico.

2. ¿Cómo puedo modificar el script para que busque en varios archivos a la vez?

Puedes modificar el script para que recorra varios archivos ampliando la opción –file para que acepte una lista de archivos o directorios. El script puede entonces iterar a través de cada archivo y realizar la búsqueda.

3. ¿Qué ocurre si el archivo de registro es muy grande?

Para archivos de registro muy grandes, el rendimiento puede convertirse en un problema. En estos casos, considera la posibilidad de optimizar la búsqueda limitando el número de líneas buscadas o utilizando herramientas más avanzadas como awk o sistemas de gestión de registros.

Implicaciones para la seguridad informática

Al automatizar la tarea de monitorizar los archivos de registro, este script puede ayudar a mejorar la seguridad de TI, garantizando que los problemas críticos se detecten y aborden con prontitud. Por ejemplo, detectar intentos de acceso no autorizados o actividad de malware en los registros puede ayudar a prevenir brechas de seguridad y reducir el riesgo de pérdida de datos.

Mejores prácticas

Cuando utilices este script, ten en cuenta las siguientes prácticas recomendadas:

  • Actualiza regularmente el script para garantizar la compatibilidad con tu entorno.
  • Utiliza parámetros de búsqueda de texto claros y específicos para evitar falsos positivos.
  • Implementa mecanismos adicionales de registro o alerta para complementar el script.

Reflexiones finales

Para los profesionales de TI y los MSP, herramientas como este script tienen un valor incalculable para automatizar tareas rutinarias y garantizar el buen estado del sistema. Al integrar estos scripts en tu flujo de trabajo, puedes centrarse en actividades más estratégicas, manteniendo la confianza en que los problemas críticos no pasarán desapercibidos. NinjaOne ofrece un conjunto de herramientas que pueden mejorar aún más tus capacidades de gestión de TI, proporcionando capas adicionales de automatización, supervisión y seguridad para apoyar tus operaciones de TI.

Categorías:

Quizá también te interese…

×

¡Vean a NinjaOne en acción!

Al enviar este formulario, acepto la política de privacidad de NinjaOne.

Términos y condiciones de NinjaOne

Al hacer clic en el botón “Acepto” que aparece a continuación, estás aceptando los siguientes términos legales, así como nuestras Condiciones de uso:

  • Derechos de propiedad: NinjaOne posee y seguirá poseyendo todos los derechos, títulos e intereses sobre el script (incluidos los derechos de autor). NinjaOne concede al usuario una licencia limitada para utilizar el script de acuerdo con estos términos legales.
  • Limitación de uso: solo podrás utilizar el script para tus legítimos fines personales o comerciales internos, y no podrás compartirlo con terceros.
  • Prohibición de republicación: bajo ninguna circunstancia está permitido volver a publicar el script en ninguna biblioteca de scripts que pertenezca o esté bajo el control de cualquier otro proveedor de software.
  • Exclusión de garantía: el script se proporciona “tal cual” y “según disponibilidad”, sin garantía de ningún tipo. NinjaOne no promete ni garantiza que el script esté libre de defectos o que satisfaga las necesidades o expectativas específicas del usuario.
  • Asunción de riesgos: el uso que el usuario haga del script corre por su cuenta y riesgo. El usuario reconoce que existen ciertos riesgos inherentes al uso del script, y entiende y asume cada uno de esos riesgos.
  • Renuncia y exención: el usuario no hará responsable a NinjaOne de cualquier consecuencia adversa o no deseada que resulte del uso del script y renuncia a cualquier derecho o recurso legal o equitativo que pueda tener contra NinjaOne en relación con su uso del script.
  • CLUF: si el usuario es cliente de NinjaOne, su uso del script está sujeto al Contrato de Licencia para el Usuario Final (CLUF).