使用 Vector 将 PostgreSQL 日志输出为 Prometheus 指标

​本文讨论使用日志作为数据源生成 Prometheus 指标。如果现有 exporters 提供的指标无法满足需求,或者 exporter 因授权原因无法对外公开,则可以参考本文提供的方式。

写本文的原因是,我们的一位客户希望能够及时获取有关从应用程序到 PostgreSQL v14 数据库的失败查询的信息。同时,我们必须在不对应用程序代码进行任何更改的情况下实现此监控。在查看现有的 PostgreSQL exporter后,我们未能找到任何能够发送错误报告的合适指标,因此我们决定自己新建一个。

1.准备日志以供进一步使用

从技术角度来看,步骤大致为:解析日志文件、从数据中提取指标、将其输出到 Prometheus 以及设置告警。早期的 PostgreSQL 版本(15 版本之前)不支持 JSON 结构化日志格式。在生产环境中安装第三方模块并不推荐,我们也与推荐以 CSV 格式存储日志数据。但是,我们能够根据需要使用配置文件来格式化输出。我们的客户使用了以下日志格式:

postgresql.conf log_line_prefix = ‘%m %p %u@%d from %h [vxid:%v txid:%x] [%i] ‘`

描述如下:

  • %m是一个时间戳,包括毫秒;
  • %p– 进程号;
  • %u- 用户名;
  • %d- 数据库名称。

有关其他变量的用途以及可以写入日志的其他信息的更多信息,请参阅 PostgreSQL 文档

(https://www.postgresql.org/docs/14/runtime-config-logging.html)。 

结果如下:

2022-05-1207:33:54.285 UTC  2672031 @ from[vxid: txid:0][] LOG:  checkpoint complete: wrote 64 buffers (0.0%);0 WAL file(s) added,0 removed,10 recycled; write=6.266
s, sync=0.004 s, total=6.285 s; sync files=10, lnotallow=0.003 s, average=0.001 s; distance=163840 kB, estimate=163844 kB

2.寻找最佳解决方案

我们尝试了 fluentd (https://docs.fluentd.org/​) 、 Promtail (https://grafana.com/docs/loki/latest/clients/promtail/​) 和 exporter (https://vector.dev/docs/) 从日志中检索指标并将它们发送到 Prometheus。

Fluentd 有一个广泛的插件系统来适应所有用例。例如, fluent-plugin-prometheus (https://github.com/fluent/fluent-plugin-prometheus) 将数据转换为指标格式并将其交付给 Prometheus。然而,自从发布 v2.0.0 以来,该项目发展缓慢。出于这个原因,我们这次决定换一种方式——尽管我们真的很喜欢 fluentd 并且经常使用它。

我们尝试的第一个工具是 Promtail。它具有解析文本日志(包括多行日志)、基于任务处理它们(包括提取指标)以及基于指定参数过滤内容的能力。

为了进行测试,我们创建了一个配置文件来计算日志行数。

这是日志处理阶段的示例:

pipeline_stages:
- multiline:
firstline:'^\[\d{4}-\d{2}-\d{2} \d{1,2}:\d{2}:\d{2}\]'
- regex:
expression:'^(?P\[\d{4}-\d{2}-\d{2} \d{1,2}:\d{2}:\d{2}\]) (?P(?s:.*))$'
- metrics:
log_lines_total:
type: Counter
description:"total number of log lines"
prefix: pg_custom_
max_idle_duration:24h
config:
match_all:true
action: inc
log_bytes_total:
type: Counter
description:"total bytes of log lines"
prefix: pg_custom_
max_idle_duration:24h
config:
match_all:true
count_entry_bytes:true
action: add

配置工作正常;然而,我们错过了一个关键点。Promtail需要Loki(Grafana开发的日志聚合工具)的地址作为强制配置参数。没有这个参数集,它根本不会启动。我们认为同时安装 Loki 是不切实际的。

注意。如果您仍然想使用 Promtail,您可以将 Loki 地址替换为任何能够为任何请求提供 200 响应代码的 Web 服务器(例如,nginx)的地址。但是,我们不建议在生产环境中使用此解决方法。

终于轮到 Vector 了。这对我们来说效果很不错。

3.Vector:解析日志并输出到 Prometheus

Vector 必须安装在要解析的日志文件所在的主机上,以便将日志输出到 Prometheus。安装完成后,进行相应的配置。你可以使用,例如,Ansible 来做到这一点:

# playbook-vector.yaml
---
- name: Setup vector
hosts:
- pg
become: yes
vars:
arch: amd64
version:0.18.1
vector_template: files/40-vector.toml
vector_config_file:/etc/vector/vector.toml
tasks:
- name: Setup install vector
become: yes
apt:
deb:"https://packages.timber.io/vector/` version `/vector-` version `-` arch `.deb"
install_recommends: yes
notify:
- restart vector


- name: Copy config
copy:
src:"` vector_template `"
dest:"` vector_config_file `"
mode:0644
owner: vector
group: vector
notify: restart vector


- name: Start Vector
service:
state: started
enabled: yes
name: vector


handlers:
- name: restart vector
service:
state: restarted
daemon_reload: yes
name: vector

Vector 配置存储在 TOML 文件中。在此文件中指定日志文件的位置及其类型:

# vector.toml
[sources.postgres_logs.multiline]
start_pattern ='^\d{4}-[0-1]\d-[0-3]\d \d+:\d+:\d+\.\d+ [A-Z]{3}'
mode ="halt_before"
condition_pattern ='^\d{4}-[0-1]\d-[0-3]\d \d+:\d+:\d+\.\d+ [A-Z]{3}'
timeout_ms =1000

请注意,halt_before​mode 意味着 Vector 会将跟在condition_pattern(并且不以后者开头)之后的所有行视为单个消息。

您也可以使用其他multiline.mode​值。例如,该half_with​模式包括所有连续的行,直到并包括与condition_pattern消息中匹配的第一行。

然后使用VRL (https://vector.dev/docs/reference/vrl) 解析消息:

# vector.toml
[transforms.postgres_remap]
type ="remap"
inputs =["postgres_logs"]
source =""". |= parse_regex!(.message, r'^(?P\\d{4}-[0-1]\\d-[0-3]\\d \\d+:\\d+:\\d+\\.\\d+ [A-Z]{3}) (?P\\d+) (?P(\\[\\w+\\]@\\w+|@|\\w+@\\w+)) from (?P(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|\\[\\w+\\]|\\s*)) (?P\\[\\w+:.+:\\d+\\]) (?P(\\[\\]|\\[\\w.+\\])) (?P.*[A-Z]): (?P.*)$')del(.timestamp)message_parts, err = split(.message, ",", limit: 2)structured = parse_key_value(message_parts[1], key_value_delimiter: ":", field_delimiter: ",") ?? {}message = message_parts[0]. = merge(., structured)del(."please try the setup again")del(.message)"""

在这里,我们:

  • 指定日志源;
  • 设置一个正则表达式来解析日志消息;
  • 删除了不必要的字段;
  • 使用“,”分隔符拆分消息;
  • 将结果保存到map数组中,对其进行处理,并获得 JSON 输出,以便我们可以继续操作其字段。

现在让我们过滤掉错误消息:

# vector.toml
[transforms.postgres_filter]
type ="filter"
inputs =["postgres_remap"]
condition ='.level == "ERROR" || .level == "FATAL"'

此配置将在指标中包含ERROR和FATAL消息。

接下来,根据过滤的日志消息创建一个指标。设置要使用的指标类型和字段,适当地命名,并附加额外的标签。

# vector.toml
[transforms.postgres_metric]
type ="log_to_metric"
inputs =["postgres_filter"]


[[transforms.postgres_metric.metrics]]
type ="counter"
field ="level"
name ="error_total"
namespace ="pg_log"


[transforms.postgres_metric.metrics.tags]
level ="`level`"
host ="`host`"

最后一步是发布 exporter。Prometheus 将使用它来抓取指标。

[sinks.postgres_export_metric]
type ="prometheus_exporter"
inputs =["postgres_metric"]
address ="0.0.0.0:9598"
default_namespace ="pg_log"

4.根据检索到的指标设置警报

为了让 Prometheus 能够从新 exporter 器中抓取指标,我们现在必须设置常规目标:

scrape_configs:
- job_name: custom-pg-log-exporter
static_configs:
- targets:['10.10.10.2:9598','10.10.10.3:9598','10.10.10.4:9598']

下一步是创建基于指标的规则,Alertmanager 将根据其路由设置处理该规则:

- alert: PgErrorCountChangeWarning
expr:| increase(pg_log_error_total{level="ERROR"}[30m])>0
for:10m
labels:
severity: warning
annotations:
summary: The amount of errors in pg host {{$labels.host}} log has changed to {{$value}}
description:| There are errors in the PostgreSQL logs on the {{$labels.host}} server.
- alert: PgErrorCountChangeCritical
expr:| increase(pg_log_error_total{level="FATAL"}[30m])>0
for:10m
labels:
severity: critical
annotations:
summary: The amount of fatal errors in pg host {{$labels.host}} log has changed to {{$value}}
description:|
There are fatal errors in the PostgreSQL logs on the {{$labels.host}} server.

pg_log_error_total这里计算向量时间序列30分钟的增量。其值大于零意味着计数器已更改,从而导致向用户发送警报。然后用户可以检查 PostgreSQL 日志以找出问题的原因。

5.结论

因此,我们使用了一个简单的错误计数器来说明如何根据日志文件设置指标收集。如果现有的 exporter 没有提供我们想要的指标,并且没有办法更改应用程序代码,这可以作为一个相对简单的解决方案。

我们的选择受到 Vector 的简单配置和广泛功能的影响,使其成为各种任务的理想选择。此外,其高性能 (https://medium.com/ibm-cloud/log-collectors-performance-benchmarking-8c5218a08fea) 意味着可用资源得到有效利用。vector top Cli工具有助于调试日志管道和查看 Vector 的指标。它在漂亮的 TUI 界面中显示信息。

Vector 不仅限于基本的计数器功能——它还可以解析日志以查找缓慢的数据库查询。然后,您可以使用 VRL 处理结果,聚合 (https://vector.dev/docs/reference/configuration/transforms/aggregate/) 它们,将它们转换为指标,然后显示 Grafana 中排名前 10 位的查询。它还可以通过处理连接日志和根据获得的数据创建指标来证明对安全审计很有用。换句话说,Vector 有很多的应用场景——这完全取决于用户的需求。

原文:https://blog.palark.com/vector-to-export-pgsql-logs-into-prometheus/​

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/298745.html<

(0)
管理的头像管理
上一篇2025-05-23 02:09
下一篇 2025-05-23 02:10

相关推荐

  • 站群服务器和普通服务器到底哪个更适合GEO,怎么选?

    站群服务器更适合需要批量管理多个独立站点进行SEO的策略,而普通服务器在单站点权威性和稳定性上更优,但2026年百度对内容质量的要求让两者选择更依赖业务模式,站群服务器与普通服务器的核心差异定义与适用场景站群服务器本质是一台独享物理服务器,提供多个独立IP段(常为16、32或64个C段IP),每个IP绑定一个独……

    2026-07-28
    0
  • 物理服务器和云服务器做站群到底选哪个,哪个更稳定?

    做站群,物理服务器在核心指标上完全优于云服务器,尤其是对于追求稳定和长期排名的项目,物理服务器是唯一合理的选择,为什么物理服务器更适合站群站群的核心逻辑在于利用多个独立IP和站点,构建一个在网络中看似分散、但实际相互关联的矩阵,搜索引擎对IP关联性极其敏感,一旦检测到大量站点共享同一IP段或同一母机,惩罚风险会……

    2026-07-28
    0
  • 国内高防服务器哪家防御真实靠谱,怎么选?

    国内高防服务器哪家防御真实靠谱?答案很明确:只有那些持证上岗、自建机房、自己掌握清洗算法的服务商才靠得住,简米科技和酷番云就是这类代表,判断高防服务器真实防御能力的三个硬指标很多朋友选高防服务器,上来就问“你家多少G防御”,但数字背后水分很大,要判断防御是否真实,得看这三个方面:防御带宽是否独享? 有些服务商宣……

    2026-07-28
    0
  • 裸金属服务器和物理服务器有什么区别?,怎么选?

    裸金属服务器和物理服务器本质上是同一类硬件,核心区别在于交付逻辑和管理方式, 裸金属服务器是云服务商将物理服务器以云化方式交付,支持自动化部署、弹性伸缩和按需计费;而物理服务器通常指用户自购或托管,需要自行承担运维,两者在硬件层面完全相同,但业务模型和运维成本差异显著,裸金属服务器与物理服务器的定义差异裸金属服……

    2026-07-28
    0
  • 做GEO站群选哪家服务器服务商靠谱,怎么选?

    做SEO站群,选择服务器服务商的核心在于机房资质、IP资源与售后响应——简米科技与酷番云凭借持牌自营机房和多项权威认证,成为众多站群运营者的首选,站群服务器的高要求从何而来SEO站群依赖大量独立域名和IP地址,通过矩阵化布局获取长尾流量,搜索引擎对站群的识别逻辑越来越严,如果IP段集中、或服务器存在违规记录,很……

    2026-07-28
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注