Monitoreo de errores y eventos en el registro de PostgreSQL (grok_exporter)

Buenas tardes, colegas y habretchiki! Hoy, me gustaría compartir con ustedes una pequeña nota sobre cómo pueden organizar el monitoreo operativo de los errores y eventos que aparecen en el registro de PostgreSQL usando Prometheus y el exportador de métricas grok_exporter.

Debo decir de inmediato que este es, por supuesto, un caso especial de uso de este exportador. Entonces, ¿por qué es necesario y quién podría estar interesado?

Introducción


¿Quién necesita esto?


Si Prometheus ya está presente en su infraestructura y crear una infraestructura separada para recopilar y analizar registros, como ELK o Greylog, es costoso y poco práctico (si no hay Prometheus, no es un problema, es fácil y rápido de instalar).

La herramienta será útil no solo para los DBA, sino también para los administradores de aplicaciones, en general, para todos aquellos que de alguna manera trabajan con registros de aplicaciones. Le permite obtener rápidamente información sobre el comportamiento independiente y tener un cierto punto de referencia para un análisis más detallado de la situación.

¿Para qué es todo esto?


Los registros de monitoreo le permitirán tener una imagen más completa y responder más rápidamente a los problemas emergentes, ya sea: intentos de autorización (incluidos los que no tuvieron éxito), varios errores o eventos específicos.

Aquí hay una buena lista, formada por categorías de eventos (consulte la sección Categorías de eventos de registro), se puede usar para crear reglas en Prometheus.

grok_exporter


El exportador de métricas grok_exporter le permite leer datos no estructurados de la fuente, convertirlos en datos estructurados, de acuerdo con las reglas, y entregarlos como métricas en un formato que Prometheus entiende.

El exportador se creó en la imagen de un complemento en ELK plugins-filters-grok , que le permite utilizar un conjunto de plantillas plugins-filters-grok tal como están.

Instalación


La instalación es sencilla y sencilla. Para hacer esto, solo siga el enlace y descargue la versión que desee (y sí, todas son de prelanzamiento, y las últimas versiones aún están en la etapa de candidato de lanzamiento) y descomprima el archivo resultante.

Como resultado, obtenemos el siguiente conjunto:

grok_exporter-1.0.0.RC3.linux-amd64
├── patterns
│   ├── ruby
│   ├── redis
│   ├── rails
│   ├── postgresql
│   ├── nagios
│   ├── mongodb
│   ├── mcollective-patterns
│   ├── mcollective
│   ├── linux-syslog
│   ├── junos
│   ├── java
│   ├── haproxy
│   ├── grok-patterns
│   ├── firewalls
│   ├── exim
│   ├── bro
│   ├── bacula
│   └── aws
├── grok_exporter
└── example
    ├── exim-rejected-RCPT-examples.log
    ├── config.yml
    └── config_logstash_http_input_ipv6.yml

dónde:

  • grok_exporter - ejecutable exportador
  • patrones : contiene un conjunto de patrones
  • ejemplo : contiene un conjunto de datos de prueba y un archivo de configuración de ejemplo

Para iniciar el exportador, simplemente ejecute el archivo ejecutable. El archivo de configuración config.yml se busca en el directorio desde donde se inicia la aplicación o su ubicación se especifica mediante la opción -config



Preparación y preparación para el trabajo.


PostgreSQL


, PostgreSQL. :


  1. grok_exporter . , pg_reload_conf.

    • alter system set log_directory to '/var/log/postgresql'; 
    • alter system set log_file_mode to '0644';
  2. log_line_prefix, . , . :

     alter system set log_line_prefix to '%t datname:%d,client:%h,app:%a,usename:%u,session:%c ';

grok_exporter


En primer lugar, editaremos la plantilla de patrones / postgresql de acuerdo con el formato de nuestro archivo de registro y agregaremos construcciones auxiliares. Una vez más, enfatizo que la sintaxis de las plantillas es totalmente consistente con la utilizada en plugins-filters-grok , por lo tanto, para todos los problemas relacionados con la sintaxis, puede y debe ir a su documentación. Entonces, traigamos nuestra plantilla para PostgreSQL al formulario (el archivo de patrones / grok-patterns ya contiene un gran conjunto de plantillas básicas):

#     - postgresql
PG_TIMESTAMP %{YEAR}-%{MONTHNUM}-%{MONTHDAY} %{HOUR}:%{MINUTE}:%{SECOND} [A-Z]{3,4}

#    
PG_ERROR_PATTERN (ERROR|WARNING|FATAL|PANIC)

# log_line_prefix   - PostgreSQL
PG_PREFIX %{PG_TIMESTAMP} datname:(%{DATA:datname})?,client:(%{DATA:client_host})?,app:(%{DATA:app_name})?,usename:(%{USER:usename})?,session:(%{DATA:session})?

#    log_level     
PG_ERROR_LEVEL %{PG_ERROR_PATTERN:log_level}:

#    
PG_EVENT_AUTH LOG:  connection authorized:

#      SIGHUP,   
PG_EVENT_RELOAD LOG:  received SIGHUP, reloading configuration files

El diseño le ()?permite indicar que el valor es opcional.


Aquí, con suficiente detalle, con ejemplos, se describe el proceso de creación de un archivo de configuración. A continuación, solo se proporciona lo que se utilizará.


Una breve descripción del archivo de configuración (de la documentación)
El archivo de configuración es un archivo en formato YAML y se divide en secciones:

  1. global - configuraciones globales
    • config_version — . grok_exporter, ≥ 1.0.0.RC3, 3
      retention_check_interval — . , .

  2. input — .

    • type — . : file, stdin, webhook. , file;
    • path|paths — c -(-). ;
    • readall — , .
      true — , . Prometheus .
      false — , grok_exporter;
    • fail_on_missing_logfile — -. true — , ;
  3. imports — , , . 2, , grok.

    • typegrok_patterns () metrics ();
    • file|dir — . , .

  4. grok_patterns — , .
  5. metrics — . — counter, gauge, histogram, or summary.
  6. server

      protocol: https
      host: localhost
      port: 9144
      path: /metrics
      cert: /path/to/cert
      key: /path/to/key
    



En la sintaxis de la tercera versión del archivo de configuración, fue posible importar métricas de archivos individuales, esto le permitirá agrupar las métricas por propósito.

A continuación, cree el archivo de configuración base config.yml . En él, nosotros: establecemos la ruta a los archivos de registro de PostgreSQL por máscara; importar plantillas del directorio de patrones y métricas del directorio metrics.d ; indicamos por qué protocolo y en qué puerto es necesario solicitar métricas.

config.yml
  config_version: 3
  retention_check_interval: 10s
input:
  type: file
  path: /var/log/postgresql/postgresql-*.log
  readall: false
imports:
- type: grok_patterns
  dir: ./patterns
- type: metrics
  dir: ./metrics.d
server:
  protocol: http
  port: 9144


, metrics.d postgresql.yml, .

, , .. ( retention, - 2 30 ) , . retention_check_interval.

, :

  • , ;
  • — GAUGE COUNTER, . .. GAUGE, ;
  • Si acumulativo se establece en verdadero, se sumarán los valores de las métricas con el mismo conjunto de etiquetas, que es el comportamiento esperado. Puede surgir una situación inesperada cuando, en la segunda solicitud, puede obtener la suma de los valores en la solicitud más el valor anterior.
  • Si acumulativo se establece en falso, si hay métricas con el mismo conjunto de etiquetas, solo se mostrará el último valor;

Resultó muchas cartas, confusas e incomprensibles en algunos lugares, pero trataré de revelar esto en los ejemplos a continuación.

Y así, tenemos un archivo de configuración que puede devolver cuatro métricas, tres contadores y un valor arbitrario. De hecho, los primeros tres consideran el número de coincidencias del campo de plantilla de coincidencia con las cadenas recibidas de la fuente, el cuarto: muestra la suma de los valores.

postgresql.yaml
#  - 
- type:   counter
  name:   pg_grok_error_count
  help:   Count of line error
  match:  '%{PG_PREFIX} %{PG_ERROR_LEVEL}  %{GREEDYDATA:message}'
  labels:
    log_level:   '{{.log_level}}'
    usename:     '{{.usename}}'
    datname:     '{{.datname}}'
    app_name:    '{{.app_name}}'
    client_host: '{{.client_host}}'
    message:     '{{.message}}'

#   
- type:   counter
  name:   pg_grok_auth_succes_count
  help:   Count of connections authorized
  match:  '%{PG_PREFIX} %{PG_EVENT_AUTH}'
  labels:
    usename:     '{{.usename}}'
    datname:     '{{.datname}}'
    app_name:    '{{.app_name}}'
    client_host: '{{.client_host}}'

#   
- type:   counter
  name:   pg_grok_reload_conf_count
  help:   Count of call pg_reload_conf
  match:  '%{PG_PREFIX} %{PG_EVENT_RELOAD}'
  labels:
    session:     '{{.session}}'

#   
- type:       gauge
  name:       pg_grok_tpm_file_size_bytes
  help:       Size of tmp file created by time
  match:      '%{PG_PREFIX} %{PG_EVENT_TMP_FILE}'
  value:      '{{.size}}'
  cumulative: true
  retention:  5s
  labels:
    static:     'temp_file'


Práctica


pg_grok_error_count


La métrica cuenta el número de eventos ERROR, WARNING, FATAL y PANIC, según el patrón. Puede ser útil para monitoreo y advertencia en caso de emergencia. Por ejemplo, puede configurar una alerta en los siguientes casos: intentos de autorización fallida, exceder el umbral del número de errores por unidad de tiempo, o cuando la base de datos está en un estado de recuperación después de una falla, y mucho más ( Categorías de eventos de registro ).

Por ejemplo, configuraremos una alerta sobre intentos fallidos de autorización. Un ejemplo de un intento de inicio de sesión fallido en el archivo de registro PostgreSQL se ve así:

2020-04-20 23:34:53 AEST datname:test,client:127.0.0.1,app:[unknown],usename:test_user,session:5e9da4fd.733 FATAL:  password authentication failed for user "test_user"
2020-04-20 23:34:53 AEST datname:test,client:127.0.0.1,app:[unknown],usename:test_user,session:5e9da4fd.733 DETAIL:  Password does not match for user "test_user".
        Connection matched pg_hba.conf line 86: "host    all             all             127.0.0.1/32            md5"

En la salida de grok_exporter, los intentos de autenticación fallidos pueden identificarse mediante la etiqueta del mensaje que contiene la autenticación de contraseña de subcadena fallida para ... :

pg_grok_error_count{app_name="[unknown]",client_host="127.0.0.1",datname="postgres",log_level="FATAL",message="password authentication failed for user "postgres"", usename="postgres"} 15
pg_grok_error_count{app_name="[unknown]",client_host="127.0.0.1",datname="test",log_level="FATAL",message="password authentication failed for user \"test_user\"",usename="test_user"} 5

Los datos obtenidos ayudarán a formular una regla para Prometeo. La sensibilidad se puede ajustar en función de sus propias realidades.

groups:
- name: AuthAlert
  rules:
  - alert: AuthFail
    expr: sum(rate(pg_grok_error_count{message=~"password authentication failed for user.*"}[1m])) by (instance) > 0.1
    for: 30s
    labels:
      severity: warning
    annotations:
      summary: Too many fail authorization for {{ $labels.instance }}

pg_grok_reload_conf_count


Del mismo modo, puede realizar un seguimiento de la ejecución del comando pg_reload_conf. Además, vale la pena prestar atención a la lista de etiquetas, o más bien, al hecho de que solo se usa una etiqueta de sesión. Esto se debe al hecho de que el evento se crea como parte del proceso del servidor y no de la sesión del usuario.

En el archivo de registro de PostgreSQL, este evento se ve así:

2020-04-21 01:20:26 AEST datname:,client:,app:,usename:,session:5e9d9371.564 LOG:  received SIGHUP, reloading configuration files

Aquellos. Se puede ver que las etiquetas utilizadas en el ejemplo anterior están vacías. En este caso, utilizaremos el identificador de sesión para la identificación, y no cambiará hasta que la instancia de PostgreSQL se detenga o reinicie.

Una situación similar será para otros casos similares, por ejemplo, detener una instancia:

2020-04-21 01:32:52 AEST datname:,client:,app:,usename:,session:5e9d9371.564 LOG:  received fast shutdown request
2020-04-21 01:32:53 AEST datname:,client:,app:,usename:,session:5e9d9371.564 LOG:  database system is shut down

En la salida de grok_exporter, obtenemos:

# HELP pg_grok_reload_conf_count Count of call pg_reload_conf
# TYPE pg_grok_reload_conf_count counter
pg_grok_reload_conf_count{session="5e9d9371.564"} 5

La regla para la notificación, no tiene sentido mencionarlo, será similar a lo discutido anteriormente.

pg_grok_tpm_file_size_bytes


Inmediatamente haga una reserva de que este ejemplo pertenece a la categoría de "caballo esférico en el vacío" y se da en mayor medida para mostrar cómo puede cambiar el comportamiento de las métricas.

El comportamiento de las métricas de indicadores puede verse influenciado por el cambio de la retención y los parámetros acumulativos . De hecho, a diferencia de un contador normal, que considera el número de líneas que coinciden con el patrón de coincidencia, el medidor le permite operar con datos del archivo de registro. Resulta que podemos acumularlo aumentando o disminuyendo en el valor obtenido, o usarlo como un valor que cambia arbitrariamente. Por lo tanto, en el primer caso, nos interesará la magnitud del incremento, en el segundo, el valor en sí mismo.

Veamos algunos ejemplos:

  1. , (cumulative: true). , , . , retention_check_interval + retention <= scrape_interval — Prometheus.

    - PostgreSQL :

    2020-04-21 02:51:15 AEST datname:,client:,app:,usename:,session:5e9dd2f3.1278 LOG:  temporary file: path "base/pgsql_tmp/pgsql_tmp4728.0", size 46931968
    2020-04-21 02:51:15 AEST datname:,client:,app:,usename:,session:5e9dd2f3.1279 LOG:  temporary file: path "base/pgsql_tmp/pgsql_tmp4729.0", size 46276608
    2020-04-21 02:51:15 AEST datname:postgres,client:[local],app:psql,usename:postgres,session:5e9dc0a8.112c LOG:  temporary file: path "base/pgsql_tmp/pgsql_tmp4396.14", size 47194112
    

    , :

    pg_grok_tpm_file_size_bytes{static="temp_file"} 1.40402688e+08
    

    .

    , :

    pg_grok_tpm_file_size_bytes{static="temp_file"} 1.1911168e+07
    

    : , .
  2. , , (retention) (cumulative: true)
    , - PostgreSQL :


    2020-04-21 03:03:40 AEST datname:,client:,app:,usename:,session:5e9dd5dc.12c6 LOG:  temporary file: path "base/pgsql_tmp/pgsql_tmp4806.0", size 46260224
    2020-04-21 03:03:40 AEST datname:,client:,app:,usename:,session:5e9dd5dc.12c5 LOG:  temporary file: path "base/pgsql_tmp/pgsql_tmp4805.0", size 46833664
    2020-04-21 03:03:40 AEST datname:postgres,client:[local],app:psql,usename:postgres,session:5e9dc0a8.112c LOG:  temporary file: path "base/pgsql_tmp/pgsql_tmp4396.15", size 47316992
    

    :

    pg_grok_tpm_file_size_bytes{static="temp_file"} 1.40402688e+08
    

    , . :

    2020-04-21 03:10:40 AEST datname:,client:,app:,usename:,session:5e9dd76e.1325 LOG:  temporary file: path "base/pgsql_tmp/pgsql_tmp4901.0", size 46776320
    2020-04-21 03:10:40 AEST datname:,client:,app:,usename:,session:5e9dd76e.1324 LOG:  temporary file: path "base/pgsql_tmp/pgsql_tmp4900.0", size 45768704
    2020-04-21 03:10:40 AEST datname:postgres,client:[local],app:psql,usename:postgres,session:5e9dc0a8.112c LOG:  temporary file: path "base/pgsql_tmp/pgsql_tmp4396.18", size 47841280
    

    :

    pg_grok_tpm_file_size_bytes{static="temp_file"} 2.80772608e+08
    

    , . , .
  3. , cumulative false , .

    :

    2020-04-21 03:41:04 AEST datname:,client:,app:,usename:,session:5e9ddea4.1393 LOG:  temporary file: path "base/pgsql_tmp/pgsql_tmp5011.0", size 11763712
    2020-04-21 03:41:04 AEST datname:,client:,app:,usename:,session:5e9ddea4.1392 LOG:  temporary file: path "base/pgsql_tmp/pgsql_tmp5010.0", size 11501568
    2020-04-21 03:41:04 AEST datname:postgres,client:[local],app:psql,usename:postgres,session:5e9dc0a8.112c LOG:  temporary file: path "base/pgsql_tmp/pgsql_tmp4396.19", size 11911168
    

    :

    # HELP pg_grok_tpm_file_size_bytes Size of tmp file created by time
    # TYPE pg_grok_tpm_file_size_bytes gauge
    pg_grok_tpm_file_size_bytes{static="temp_file"} 1.1911168e+07
    

    , . , .


Indudablemente, grok_exporter es la herramienta adecuada para monitorear aplicaciones. Le permite buscar en el "difícil acceso", para sistemas de monitoreo, lugares y enriquecer el monitoreo con métricas adicionales (control), sin dejar de ser bastante simple, funcional y ligero.

Al mismo tiempo, también será útil para los desarrolladores, ya que proporciona al menos acceso indirecto a los registros de aplicaciones a través de un sistema de monitoreo. Donde puede correlacionar métricas de varias fuentes.

Otro punto positivo es que el proyecto se está desarrollando y adquiere una nueva funcionalidad.

A su vez, espero que esta breve nota sea útil, incluso para el proyecto en sí. ¡Más estrellas, más trabajo divertido!

¡Gracias a todos!

Source: https://habr.com/ru/post/undefined/


All Articles