监视PostgreSQL日志中的错误和事件(grok_exporter)

下午好,同事们,哈布列奇基!今天,我想与大家分享一下如何使用Prometheus和指标grok_exporter的输出来组织对PostgreSQL日志中出现的错误和事件进行操作监控的小注释。

我必须马上说,这当然是使用此导出器的一种特殊情况。那么为什么需要它,谁可能对此感兴趣呢?

介绍


谁需要这个?


如果您的基础架构中已经存在Prometheus,并且创建用于收集和分析日志的单独的基础架构(例如ELK或Greylog),则既昂贵又不切实际(如果没有Prometheus,就不成问题,安装起来就容易又快捷)。

该工具不仅对DBA有用,而且对所有以某种方式使用应用程序日志的人来说,对于应用程序管理员也将是有用的。它使您可以快速获取有关自由​​职业者行为的信息,并为进一步分析情况提供一定的参考点。

这都是为了什么?


监视日志将使您更完整地了解情况,并能更快地对出现的问题做出响应:授权尝试(包括失败的尝试),各种错误或特定事件。

这里有一个很好的列表,由事件类别组成(请参阅“记录事件类别”部分),可用于在Prometheus中创建规则。

grok_exporter


度量标准导出器grok_exporter允许从源读取非结构化数据,根据规则将其转换为结构化数据,并以Prometheus理解的格式作为度量标准分发。

导出程序是在ELK plugins-filters-grok中的一个插件映像中创建的,它使您可以按原样使用一组plugins-filters-grok模板

安装


安装简单明了。为此,只需点击链接并下载所需的版本(是的,它们都是预发行版本,而最新版本仍处于候选发行阶段)并解压缩所得的存档。

结果,我们得到以下设置:

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

哪里:

  • grok_exporter-出口商可执行文件
  • 模式 -包含一组模式
  • 示例 -包含测试数据集和示例配置文件

要启动导出器,只需运行可执行文件。在启动应用程序或通过-config选项指定其位置的目录中搜索config.yml配置文件



设置和准备工作


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


首先,我们将根据日志文件的格式编辑patterns / postgresql模板,并添加辅助构造。我再次强调,模板的语法与plugins-filters-grok中使用的语法完全一致,因此,对于与该语法有关的所有问题,您可以并且应该查阅其文档。因此,让我们将PostgreSQL的模板带到表单中(patterns / grok-patterns文件已经包含了很多基本模板):

#     - 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

该设计()?使您可以指示该值是可选的。


在此,以示例的方式足够详细地描述创建配置文件的过程。下面,仅给出将要使用的内容。


配置文件的简要说明(来自文档)
YAML :

  1. global
    • 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
    



使用第三版配置文件的语法,可以从单个文件中导入指标,这将使您可以按目的对指标进行分组。

接下来,创建基本的config.yml配置文件在其中,我们:通过mask设置PostgreSQL日志文件的路径;patterns目录导入模板,metrics.d目录导入度量; 我们通过什么协议和在哪个端口上指示必须申请指标。

配置文件
  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, ;
  • 如果累计设置为true,则指标将使用相同的标签集求和,这是预期的行为。当您在第二个请求中获得请求中的值加上前一个值的总和时,可能会出现意外情况。
  • 如果将cumulative设置为false,则如果具有带有相同标签集的度量标准,则仅显示最后一个值;否则,将显示最后一个值。

事实证明,很多地方的来信令人困惑不解,但我将尝试在以下示例中进行披露。

因此,我们有一个配置文件,该文件可以返回四个指标,三个计数器和一个任意值。实际上,前三个考虑匹配模板字段与从源接收到的字符串的匹配数,第四个-显示值的总和。

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'


实践


pg_grok_error_count


度量标准根据模式对错误,警告,致命和紧急事件的数量进行计数。在紧急情况下对监视和警告很有用。例如,您可以在以下情况下配置警报:未成功授权的尝试,超过每单位时间错误数的阈值,失败后数据库处于恢复状态时以及更多(日志事件类别)。

例如,我们将设置有关授权尝试失败的警报。PostgreSQL日志文件中的登录尝试失败的示例如下所示:

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"

在grok_exporter的输出中,可以通过消息标签识别失败的身份验证尝试,该消息标签包含...的子字符串密码身份验证失败

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

获得的数据将有助于制定普罗米修斯的规则。灵敏度可以根据您自己的实际情况进行调整。

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


同样,您可以跟踪pg_reload_conf命令的执行。而且,值得关注标签列表,或者更确切地说,仅使用一个会话标签这一事实。这是由于该事件是作为服务器进程而不是用户会话的一部分创建的事实。

在PostgreSQL日志文件中,此事件如下所示:

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

那些。可以看出,在前面的示例中使用的标签是空的。在这种情况下,我们将使用会话标识符进行标识,并且在PostgreSQL实例停止或重新启动之前它不会更改。

其他类似情况也会出现类似情况,例如,停止实例:

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

在grok_exporter的输出中,我们得到:

# 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

通知规则,毫无意义,与上面讨论的相似。

pg_grok_tpm_file_size_bytes


立即保留该示例来自“真空中的球形马”类别的权限,并在更大范围内给出该示例,以显示如何更改度量标准的行为。可以通过更改保留值累积参数来影响量规指标

的行为。的确,与常规计数器不同(常规计数器考虑匹配模式的行数),使用gauge可以对日志文件中的数据进行操作。事实证明,我们可以通过增加或减少获得的值来对其进行累加,或者将其用作任意更改的值。因此,在第一种情况下,我们将对增量的大小感兴趣,在第二种情况下,我们将对增量本身感兴趣。 让我们看几个例子:



  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
    

    , . , .


毫无疑问grok_exporter是监视应用程序的正确工具。它使您可以查看“难于访问”的监视系统,位置,并通过其他(控制)指标来丰富监视,同时保持非常简单,功能强大和轻巧的特性。

同时,它对开发人员也很有用,因为它至少可以通过监视系统间接访问应用程序日志。您可以在其中关联来自各种来源的指标。

另一个积极的方面是该项目正在开发并获得新功能。

反过来,我希望这篇简短的笔记对项目本身也会有所帮助。更多星星,更多有趣的工作!

谢谢大家!

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


All Articles