Tips, Soluciones y Novedades en Tecnología

Mostrando entradas con la etiqueta Elastic. Mostrar todas las entradas
Mostrando entradas con la etiqueta Elastic. Mostrar todas las entradas

04/06/2023

Enviar Logs desde Spring Boot a Logstash


La gestión de logs en proyecto java, normalmente se registran en archivos según la configuración va generando historial con el tiempo.

Para tener disponible mediante acceso web a los logs del servidor, una buena practica es gestionar con herramientas especializadas y segun nuestras necesidades explotar esos logs con el obetivo de entender mejor que esta pasando en el funcionamiento de nuestra aplicación

En este Post veremos como configurar la librería Logback que permite enviar logs desde un proyecto Spring Boot al servidor LogStash, y este podrá enviar a un servidor ElasticSearch u otro segun necesidad.

Agregamos la dependencia maven al proyecto

<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>6.6</version>
</dependency>

Configuración de Logback junto al archivo de application.yml de spring

logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property resource="application.yml" />
    <springProperty scope="context" name="logstash" source="logging.logstash.url"/>
    <springProperty scope="context" name="loglevel" source="logging.level.root"/>
    <include resource="org/springframework/boot/logging/logback/base.xml"/>
    <appender name="logstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
        <destination>${logstash}</destination>
        <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
            <providers>
                <mdc />
                <context />
                <logLevel />
                <loggerName />
                <pattern>
                    <pattern>
                        {
                        "app": "myapp"
                        }
                    </pattern>
                </pattern>
                <threadName />
                <message />
                <logstashMarkers />
                <stackTrace />
            </providers>
        </encoder>
    </appender>
    <logger level="${loglevel}">
        <appender-ref ref="logstash"/>
    </logger>
    <root level="${loglevel}">
        <appender-ref ref="logstash"/>
    </root>
</configuration>

Ahora configuramos el archivo application.yml del proyecto de Spring.

# Configuración de Logs
logging:
  file:
    name: /opt/apps/myapp.log
    max-size: 10MB
    max-history: 30
    clean-history-on-start: true
  logstash:
    url: logstash.mydominio.com:5000
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{15} - %msg%n"
  level:
    root: INFO
    org.springframework.web: INFO

Como se puede apreciar, en la secion "logging" se define file y logstash, esto permitirá escribir los logs en disco y enviar a logstash al mismo tiempo.

Ahora vamos a ver el contenido del archivo de configuración de logstash que estará escuchando en el puerto 5000, esperando que logback envie los logs desde spring boot.

Crear el archivo apps.conf en /etc/logstash/conf.d

input {
  tcp {
        port => "5000"
        codec => json_lines
    }
}
filter {
}
output {
  elasticsearch {
    hosts => ["https://localhost:9200"]
    user => "logstash"
    password => "123456789"
    cacert => "/etc/logstash/certs/http_ca.crt"
    ssl => true
    ssl_certificate_verification => false
    index => "miempresa-apps-%{+YYYY.MM.dd}"
  }
}

El codigo de la configuración de logstash decepciona el log, no aplica filtro y envía a elasticsearch para su indexación y su posterior visualización desde Kibana, similar a la imagen siguiente.



Saludos.




Envía alertas por correo electrónico sin licencia (Gold) de Kibana


Las notificaciones en Elastic Kibana Free edition, están restringidas a solo la creación de índice y registro en log,  usar otro tipos de conectores, requiere una licencia Gold.



Nuestro objetivo es enviar correo, incluso mensaje de texto con cada alerta que se generan en kibana, para ello vamos apoyarnos de librerías y utilitarios en linux, en este post se ha realizado el envío desde un Linux Ubuntu 22.04.

Instalamos requeridas:

apt-get install swatch

apt-get install jq

apt-get install mailutils

Ahora debemos identificar la ruta de log de kibana, normalmente es:

/log/kibana/kibana.log

Cada vez que se genera una alerta, se registrará en el log, un mensaje similar a esta:

{"service":{"node":{"roles":["background_tasks","ui"]}},"ecs":{"version":"8.4.0"},"@timestamp":"2023-06-04T22:20:32.081+00:00","message":"Server log: Monitor (Nombre del monitor XXX) with url https://api.miempresa.com/api/clientes has recovered with status Up","log":{"level":"INFO","logger":"plugins.actions.server-log"},"process":{"pid":543029},"trace":{"id":"4c78054535a5a5fa47375001a7c3a01d"},"transaction":{"id":"ca3102c7e809fce5"}}

Ahora creamos el archivo .swatchdogrc:

vi /root/.swatchdogrc

/root/scripts/swatchdog-notify.sh
watchfor /Server log/
exec /root/scripts/swatchdog-notify.sh '$_'

Creamos el archivo swatchdog-notify.sh

#!/bin/bash
echo $1 > message.txt
mensaje=$(jq ".message" message.txt)
if [[ $(echo "$mensaje" | grep -i "Monitor") ]]; then
    if [[ $(echo "$mensaje" | grep -i "Up") ]]; then
       monitor=$(echo "$mensaje" | grep -oP '\((.*?)\)' | head -1 | tr -d '()')
       CONTENT=$(sed -e 's/{{monitor}}/'"$monitor"'/g' -e 's|{{status}}|'"$mensaje"'|g' -e 's/{{mensaje}}/DISPONIBLE/g'  -e 's/{{color}}/green/g' -e 's/{{color2}}/green/g' /opt/elastic/template/template_email_alert.html)
       mail -a "Content-Type: text/html"  -s "Alerta - Monitoreo $monitor" -a "From: alerts_elastic@midomain.com" $(cat /opt/elastic/notificacion/list_emails_alerts.txt) <<< $CONTENT
       /opt/elastic/scripts/script_enviar_sms.sh "$monitor" "DISPONIBLE"
       echo "Correo enviado correctamente STATUS ..."
    else
       monitor=$(echo "$mensaje" | grep -oP '\((.*?)\)' | head -1 | tr -d '()')
       CONTENT=$(sed -e 's/{{monitor}}/'"$monitor"'/g' -e 's|{{status}}|'"$mensaje"'|g' -e 's/{{mensaje}}/NO DISPONIBLE/g'  -e 's/{{color}}/red/g' -e 's/{{color2}}/red/g'  /opt/elastic/template/template_email_alert.html)
       mail -a "Content-Type: text/html"  -s "Alerta - Monitoreo $monitor" -a "From: alerts_elastic@midomain.com"  $(cat /opt/elastic/notificacion/list_emails_alerts.txt) <<< $CONTENT
       /opt/elastic/scripts/script_enviar_sms.sh "$monitor" "NO DISPONIBLE"
       echo "Correo enviado correctamente ERROR ..."
    fi
else
     echo "No tiene formato de monitoreao elastic"
fi


El script del código anterior, realiza una extracción de ciertos campos de la alerta del log y envía un correo mediante mailutils, además ejecuta otro script para enviar mensaje de texto con el asunto de la notificación, para el envio de correo utiliza una plantilla en formato html y una lista .txt en el cual se apilan los correos.

Este script se ejecutará cada vez que se genere una alerta, el cual es muy util para notificar a los encargados cuando unos de los monitores registrados mediante heartbeat falle o tengo algún error.

Ahora lo que se necesita es crear el servicio de swatch:

[Unit]
Description=Swatchdog Service
After=network.target
[Service]
Type=forking
User=root
ExecStart=/usr/bin/swatchdog --daemon -c /root/.swatchdogrc -t '/var/log/kibana/kibana.log'
[Install]
WantedBy=multi-user.target

Iniciamos el servicio:

systemctl start swatch

Al ser un servicio, swatch detectará cambios en el log y ejecutará el script de la configuración y podremos enviar notificaciones a correos y otros servicios según nuestras necesidades.





El código completo y funcional lo pueden encontrar en el repositorio de GitHub