Saltar al contenido principal
Version: Next

Logs

Sin importar el tipo de aplicación que se esté desplegando los logs siempre son una pieza importante de la solución. En entornos de microservicios son todavía más importantes.

La forma más popular de resolver el problema de centralización y visualización de logs es a través del stack ELK. Esta solución es muy robusta y provee muchas features, pero su operación, en especial Elastic Search, es bastante compleja. Por eso, si no se cuenta con un stack ELK como servicio, quizá sea mejor analizar otras opciones.

Otra solución que está ganando tracción es Grafana Loki. Esta solución hace foco en la facilidad de operación a costa de indexar los logs sobre labels en vez de hacer full-text-search.

A continuación se muestra una forma de realizar una instalación funcional mínima de Loki, Grafana y Prometheus, ya que es la herramienta con la que venimos trabajando. Vale la pena aclarar, que si en su institución se decide ir por alguna otra solución sería bueno que comparta su experiencia con la comunidad.

Modificación de dominio base

Para facilitar los siguientes pasos, deberia encontrarse ubicado en el directorio expedientes

Ejecute el siguiente comando para hacer el cambio de dominio base

export DOMAIN_NAME_URL=universidad.edu.ar
sed -i "s/uunn\.local/${DOMAIN_NAME_URL}/g" \
./prod/servicios/monitoreo.yml \
./prod/servicios/config/prometheus.yml \
./prod/servicios/config/grafana/provisioning/datasources/datasource.yml

Servicio de Loki

Password de acceso

Para generar la password de loki, debemos modificar del comando debajo la seccion de < password.loki > con la contraseña que queramos asignarle, la cual se encriptara y se guardara en la variable $CLAVE

CLAVE=$(openssl passwd -apr1  < password.loki >  | sed 's/\$/\$\$/g')
echo $CLAVE

Ésta misma clave encriptada la guardaremos en ./prod/servicios/monitoreo.yml mediante el siguiente sed.

sed -i "s/password\.loki/${CLAVE}/g" \
./prod/servicios/monitoreo.yml

Luego la clave sin encriptar debemos guardarla en los siguientes archivos ./prod/servicios/config/grafana/provisioning/datasources/datasource.yml y ./prod/servicios/promtail/promtail-config.yml mediante el sed.

export CLAVE= < password.loki.sinEncriptar > 

sed -i "s/password\.loki/${CLAVE}/g" \
./prod/servicios/config/grafana/provisioning/datasources/datasource.yml \
./prod/servicios/promtail/promtail-config.yml

En caso que el ambiente en el que este desplegando los servicios utilice una CA auto firmada, debe dirigirse en este paso a ./prod/servicios/config/grafana/provisioning/datasources/datasource.yml y descomentar los parametros tlsSkipVerify para que grafana pueda configurar correctamente los datasource

Plugin loki en docker swarm

Instalación

Para configurar el plugin de loki ejecutar en cada nodo de swarm el comando:

docker plugin install grafana/loki-docker-driver:2.3.0 --alias loki --grant-all-permissions

Configuración tentativa

Para que cada nodo del swarm envíe automaticamente los logs a loki debemos crear el archivo de configuracion del daemon de docker. Para esto, creamos el archivo /etc/docker/daemon.json con el siguiente contenido (prestando especial atencion a la indentación y el formateo .json)

{
"debug" : false,
"log-driver": "loki",
"log-opts": {
"loki-url": "https://loki: < password.loki > @ < DOMAIN_NAME_URL > /loki/loki/api/v1/push",
"loki-batch-size": "400",
"loki-timeout": "3s",
"loki-retries": "3"
}
}

En caso de ser necesario mas detalles de los logs, hay que cambiar la variable "debug" : true (tener en cuenta que en un entorno productivo tener logs a nivel debug pueden ocupar mucho espacio en el disco).

Para poder utilizar certificados self-signed deberá insertar la siguiente linea:

"loki-tls-insecure-skip-verify": "true"

Una vez que el archivo esté creado, para que se apliquen los cambios debemos reiniciar docker (para esto se podria utilizar systemctl restart docker). Tener en cuenta que esto conllevara a que se reinicien todos los contenedores que tenemos levantados.

Para mas información o configuraciones adicionales la documentación del plugin es esta https://github.com/grafana/loki/blob/v1.5.0/docs/clients/docker-driver/README.md

Configuración alternativa

Si no desea los logs del nodo completo puede configurar loki por servicio:
https://grafana.com/docs/loki/latest/clients/docker-driver/configuration/
o por contenedor:
https://grafana.com/docs/loki/latest/clients/docker-driver/configuration/

Servicio de Prometheus

Previo a inicializar prometheus junto con los servicios exportadores de metricas (node-exporter, cAdvisor, blackbox-exporter y postgres exporter) debemos realizar una configuracion inicial especificamente para asegurarnos del correcto funcionamiento del postgres exporter:

Configuracion inicial

En primera instancia debemos crear un usuario en postgres para el exportador, asignarle una contraseña, y darle acceso a pg_monitor. Esto lo haremos entrando en la db y ejecutando el siguiente comando:

CREATE USER postgres_exporter WITH PASSWORD ' < password > ';
GRANT pg_monitor to postgres_exporter;

Posterior a haber creado el nuevo usuario para postgres_exporter, debemos crear un secret del mismo, con la misma pass, de la siguiente manera:

printf ' < password > ' | docker secret create pgexporter_pass -

Luego tenemos que ir al archivo prod/servicios/monitoreo.yml y cambiar los valores de conexión a la db:

    environment:
- DATA_SOURCE_URI=postgres-db:5432/postgres?sslmode=disable
- DATA_SOURCE_USER=postgres_exporter
- DATA_SOURCE_PASS_FILE=/run/secrets/pgexporter_pass
- PG_EXPORTER_EXTEND_QUERY_PATH=/etc/postgres_exporter/queries.yaml

Finalmente, en caso que la base de datos se encuentre en un servidor externo y no local, debemos habilitar el acceso a este nuevo usuario a dicha base para su correcta conexión. Para hacer esto, es necesario agregar la siguiente linea en /etc/postgresql/ < version > /main/pg_hba.conf

host all postgres_exporter < ip-del-servidor-con-postgres-exporter > md5

(Opcional) Endpoint de acceso para prometheus

NOTA: En caso de no activar el endpoint de acceso a prometheus, proseguir con la parte de configuracion Grafana.

Activar el endpoint de acceso a prometheus nos permitirá acceder al dashboard del mismo. Con él es posible verificar servicios de los cuales se colectan logs y su estado. Sin embargo en un ambiente productivo no es recomendado habilitar el endpoint sin un ipwhitelist de por medio (ya sea de traefik u otro proxy reverso), de lo contrario podria accederse desde cualquier lado.

Para activar el endpoint de prometheus y asi poder ver su dashboard lo que tenemos que hacer es ingresar en monitoreo.yml y descomentar las siguientes labels:

      labels:
- "traefik.enable=true"
- "traefik.http.routers.prometheus.entrypoints=web-secured"
- "traefik.http.routers.prometheus.rule=Host(`uunn.local`) && PathPrefix(`/prometheus`)"
- "traefik.http.routers.prometheus.tls=true"
- "traefik.http.middlewares.prometheus-auth.basicauth.users=prometheus:$$apr1$$nJtnozKc$$VHJC0yD2C398geG/5Yu/e1"
- "traefik.http.routers.prometheus.middlewares=prometheus-auth@docker"
- "traefik.http.services.prometheus.loadbalancer.server.port=9090"

Luego en el ./config/prometheus.yml debemos descomentar la siguiente seccion y proceder a comentar la parte de dns_sd_configs:

metrics_path: /prometheus/metrics
scrape_interval: 15s
scheme: https
static_configs:
- targets: ['uunn.local']
basic_auth:
username: 'prometheus'
password: 'password.prometheus'

Para generar la password de prometheus seguiremos los mismos pasos que cuando generamos la password de loki

CLAVE=$(openssl passwd -apr1  < password.prometheus >  | sed 's/\$/\$\$/g')
echo $CLAVE

Ésta misma clave encriptada la guardaremos en ./prod/servicios/monitoreo.yml mediante el siguiente sed.

sed -i "s/password\.prometheus/${CLAVE}/g" \
./prod/servicios/monitoreo.yml

Luego la clave sin encriptar debemos guardarla en los siguientes archivos ./prod/servicios/config/grafana/provisioning/datasources/datasource.yml y ./prod/servicios/promtail/promtail-config.yml mediante el sed.

export CLAVE= < password.prometheus.sinEncriptar > 

sed -i "s/password\.prometheus/${CLAVE}/g" \
./prod/servicios/config/prometheus.yml \
./prod/servicios/config/grafana/provisioning/datasources/datasource.yml

Por ultimo tenemos que ir a datasource.yml comentar la url que esta por defecto, y descomentar la url que se va a utilizar url: https://uunn.local/prometheus

Luego en ese mismo archivo mas abajo encontraremos la seccion basicAuth el cual deberemos poner en true, descomentar el basicAuthPassword y constatar que tenga el usuario y password correspondiente

  #  < bool >  enable/disable basic auth
basicAuth: false
# < string > basic auth username, if used
basicAuthUser: prometheus
secureJsonData:
basicAuthPassword: password.loki

Finalmente solo queda volver a deployear el stack de monitoreo y tendriamos habilitado el endpoint uunn.local/prometheus.

(Opcional) Servicio de Promtail

Promtail es un servicio (agente) encargado de enviar el contenido de los logs locales del sistema a una instancia centralizada de grafana/loki. Permite integrar sistemas y/o servicios tipo "legacy", ya sean instalados "onpremise" por fuera de un cluster Docker Swarm, o que generan logs en múltiples archivos.

Nota: Debe ser desplegado en cada uno de los servidores en donde se requiera recolectar logs locales para ser enviados a grafana/loki.

A modo explicativo, se describirá a continuación el contenido de los archivos esenciales para desplegar este servicio mediante Docker (pero en otro servidor, fuera del cluster Docker Swarm). Es posible utilizar además los archivos que se encuentran en el repositorio de EEI en la carpeta "servicios/promtail", los cuales ya tienen cargados los paths de algunos servicios esenciales (Apache2, PostgresSQL, etc) y posibles aplicativos satélites del EEI (Pilaga, Diaguita, Mapuche).

docker-compose.yml

Este es el archivo donde levantaremos un contenedor de promtail. Es importante entender que en este mismo archivo debe montarse como volumenes los logs que querramos que lea promtail debajo del parametro volumes. A modo de ejemplo están comentadas 2 lineas.

Notas:

  • El parametro restart:always es para que en caso de que se reinicie el servidor/docker el contenedor se vuelva a levantar automáticamente.
  • El volumen ${PWD}:/mnt/config básicamente monta el archivo de config en el mismo path/directorio que el archivo compose. Esto lo termina confirmando promtail en la linea command: -config.file=/mnt/config/promtail-config.yml. Si decide guardar el archivo de configuración en un directorio distinto, debe modificar éste volumen por el path/directorio que corresponda.
version: "3.9"
services:
promtail:
image: grafana/promtail:2.6.1
volumes:
#Formato: - < Directorio/del/path/local > : < Directorio/del/path/contenedor >
#Ejemplo: - /var/log/apache2:/srv/apache2 o /var/log/apache2:/srv/apache2:ro para montar como read-only
- ${PWD}:/mnt/config
command: -config.file=/mnt/config/promtail-config.yml
restart: always

promtail-config.yml

Archivo de configuracion. Aquí se especificará tanto la url del servicio de loki donde enviaremos los logs, como los labels y otros datos referidos a los logs montados en el contenedor.

Notas:

  • Debajo del bloque clients está el parametro url. Acá debe modificarse el endpoint al correspondiente al servicio de loki donde promtail centralizará los logs.
  • En caso de probar esta instalación en un ambiente de desarrollo/prueba con un certificado autofirmdao se debe cambiar el valor del parámetro insecure_skip_verify a true ya que de otra manera promtail arrojará un error.
  • Para más información acerca del bloque scrape_configs y sobre __path__, referirse al README ubicado en la carpeta servicios/promtail.
server:
http_listen_port: 9080
grpc_listen_port: 0

positions:
filename: /tmp/positions.yaml

clients:
- url: https:// < loki.user > : < loki.pass > @ < uunn.siu.edu.ar > /loki/loki/api/v1/push
tls_config:
insecure_skip_verify: false # dejar en true para ambiente de desarrollo, con certificado self signed

scrape_configs:
- job_name: system
static_configs:
- targets:
- localhost
labels:
job: legacyappslogs
source: stderr
host: < nombre-del-server >
__path__: /srv/*/error.log # el path debe ser de donde se encuentra el log en el contenedor, NO en el host.

Finalmente para levantar el servicio, basta con solo usar docker compose up

Configuración grafana

Crear secret

La clave de grafana se puede generar con

printf 'grafanapassword' | docker secret create grafana_pass -

o mediante el ./prod/arai/secrets.sh.dist con el resto de las claves

Acceso desde otras redes

Por default Grafana solo soporta acceso local. para setear las redes desde las cuales necesita acceder puede editar prod/servicios/monitoreo.yml la sección

        - "traefik.http.middlewares.grafana-ipwhitelist.ipwhitelist.sourcerange=127.0.0.1/32, < IP-RED/MASCARA > "

reemplace < IP-RED/MASCARA > por la IP o RED a autorizar el acceso

Deploy del stack

En el directorio prod/servicios/ se incluye un stack mínimo de deploy de monitoreo. Para utilizarlo, ejecute:

docker stack deploy \
-c prod/servicios/monitoreo.yml \
monitoreo

Es importante notar estos 2 volumenes:

  • log-data. Este volumen es el que se debe backupear para salvar la historia de logs.
  • grafana-data. Este volumen es el que debe backupear para salvar la configuración, usuarios y dashboards de Grafana.

Acceso y configuracion de Grafana

Para poder acceder a la aplicación desde el navegador universidad.edu.ar/metricas utilice como credencial de usuario admin y como clave la que usted haya setteado en el secret.

Siga las instrucciones en https://github.com/grafana/loki/blob/v1.5.0/docs/getting-started/grafana.md#loki-in-grafana para poder ver los logs a través de Grafana.

Con respecto a loki: tenga en cuenta que instalación NO es escalable horizontalmente ya que utiliza un backend de Storage (BoltDB) que no lo soporta. Es decir, no puede haber más de 1 replica del servicio. Si esto es deseable, por el momento puede referirse a la documentación de Loki: https://github.com/grafana/loki/tree/v1.5.0/docs.

Siga las instrucciones en (grafana-dashboard.md) para poder configurar los dashboards predeterminados de EEI.

Visualización de logs

Si todo funcionó correctamente, a medida que vaya interactuando con los contenedores de su clúster los logs empezarán a aparecer en Grafana. Por defecto se puede filtrar por las siguientes categorías: Log Labels

También puede construir queries bastante más ricas utilizando el lenguaje provisto por la herramienta, llamado LogQL