Skip to main content

Postgresql Receiver

Status Available in: contrib Maintainers: @antonblock, @ishleenk17, @Caleb-Hurshman Source: opentelemetry-collector-contrib

Supported Telemetry

Logs Metrics

Overview

Prerequisites

See PostgreSQL documentation for supported versions. The monitoring user must be granted SELECT on pg_stat_database.
[!NOTE] The feature gate receiver.postgresql.separateSchemaAttr addresses an inconsistency in how schema names are reported across different metric types. When enabled, schema names are consistently reported in a dedicated postgresql.schema.name resource attribute. Status: Alpha (disabled by default) When disabled (default behavior):
  • Table metrics: postgresql.table.name = "schema_name.table_name" (schema included)
  • Index metrics: postgresql.table.name = "table_name" (schema missing)
  • Function metrics: Schema reported separately in some cases
When enabled (recommended for consistency):
  • All metrics consistently use:
    • postgresql.schema.name = "schema_name"
    • postgresql.table.name = "table_name"
This ensures reliable correlation of metrics when tables with identical names exist across different schemas. To enable:
otelcol-contrib --feature-gates=receiver.postgresql.separateSchemaAttr
See https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/29559 for more details.

Configuration

The following settings are required to create a database connection:
  • username
  • password
The following settings are optional:
  • endpoint (default = localhost:5432): The endpoint of the PostgreSQL server. Whether using TCP or Unix sockets, this value should be host:port. If transport is set to unix, the endpoint will internally be translated from host:port to /host.s.PGSQL.port
  • transport (default = tcp): The transport protocol being used to connect to PostgreSQL. Available options are tcp and unix.
  • databases (default = []): The list of databases for which the receiver will attempt to collect statistics. If an empty list is provided, the receiver will attempt to collect statistics for all non-template databases.
  • exclude_databases (default = []): List of databases which will be excluded when collecting statistics.
The following settings are also optional and nested under tls to help configure client transport security
  • insecure (default = false): Whether to enable client transport security for the PostgreSQL connection.
  • insecure_skip_verify (default = true): Whether to validate server name and certificate if client transport security is enabled.
  • cert_file (default = $HOME/.postgresql/postgresql.crt): A certificate used for client authentication, if necessary.
  • key_file (default = $HOME/.postgresql/postgresql.key): An SSL key used for client authentication, if necessary.
  • ca_file (default = ""): A set of certificate authorities used to validate the database server’s SSL certificate.
  • collection_interval (default = 10s): This receiver collects metrics on an interval. This value must be a string readable by Golang’s time.ParseDuration. Valid time units are ns, us (or Β΅s), ms, s, m, h.
  • initial_delay (default = 1s): defines how long this receiver waits before starting.

Query Sample Collection

We provide functionality to collect the query sample from PostgreSQL. It will get historical query from pg_stat_activity. To enable it, you will need the following configuration
...
    events:
      db.server.query_sample:
        enabled: true
...
By default, query sample collection is disabled, also note, to use it, you will need to grant the user you are using pg_monitor. Take the example from testdata/integration/init.sql
GRANT pg_monitor TO otelu;
The following options are available:
  • max_rows_per_query: (optional, default=1000) The max number of rows would return from the query against pg_stat_activity.

Top Query Collection

We provide functionality to collect the most executed queries from PostgreSQL. It will get data from pg_stat_statements and report incremental value of total_exec_time, total_plan_time, calls, rows, shared_blks_dirtied, shared_blks_hit, shared_blks_read, shared_blks_written, temp_blks_read, temp_blks_written. To enable it, you will need the following configuration
...
    events:
      db.server.top_query:
        enabled: true
...
Along with those attributes, we will also report the query plan we gathered if it is possible. By default, top query collection is disabled, also note, to use it, you will need to create the extension to every database. Take the example from testdata/integration/02-create-extension.sh
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
The following options are available:
  • max_rows_per_query: (optional, default=1000) The max number of rows would return from the query against pg_stat_statements.
  • top_n_query: (optional, default=200) The maximum number of active queries to report (to the next consumer) in a single run.
  • max_explain_each_interval: (optional, default=1000). The maximum number of explain query to be sent in each scrape interval. The top query collection would not get the query plan directly. Instead, we need to mimic the query in the database and get the query plan from database separately. This could lead some resources usage and limit this will reduce the impact on your database.
  • query_plan_cache_size: (optional, default=1000). The query plan cache size. Once we got explain for one query, we will store it in the cache. This defines the cache’s size for query plan.
  • query_plan_cache_ttl: (optional, default=1h). How long before the query plan cache got expired. Example values: 1m, 1h.
  • collection_interval: (optional, default=60s). This receiver can collect top_query metrics on an interval. If not provided then the global collection_interval takes effect. This value must be a string readable by Golang’s time.ParseDuration. Valid time units are ns, us (or Β΅s), ms, s, m, h.

Example Configuration

receivers:
  postgresql:
    endpoint: localhost:5432
    transport: tcp
    username: otel
    password: ${env:POSTGRESQL_PASSWORD}
    databases:
      - otel
    collection_interval: 10s
    tls:
      insecure: false
      insecure_skip_verify: false
      ca_file: /home/otel/authorities.crt
      cert_file: /home/otel/mypostgrescert.crt
      key_file: /home/otel/mypostgreskey.key
    events:
      db.server.query_sample:
        enabled: true
      db.server.top_query:
        enabled: true
    query_sample_collection:
      max_rows_per_query: 100
    top_query_collection:
      max_rows_per_query: 100
      top_n_query: 100
      collection_interval: 60s
The full list of settings exposed for this receiver are documented in config.go with detailed sample configurations in testdata/config.yaml. TLS config is documented further under the opentelemetry collector’s configtls package.

Connection pool feature

The feature gate receiver.postgresql.connectionPool allows to enable the creation & reuse of a pool per database for the connections instead of creating & closing on each scrape. This is generally a useful optimization but also alleviates the volume of generated audit logs when the PostgreSQL instance is configured with log_connections=on and/or log_disconnections=on. When this feature gate is enabled, the following optional settings are available nested under connection_pool to help configure the connection pools:
  • max_idle_time: The maximum amount of time a connection may be idle before being closed.
  • max_lifetime: The maximum amount of time a connection may be reused.
  • max_idle: The maximum number of connections in the idle connection pool.
  • max_open: The maximum number of open connections to the database.
Those settings and their defaults are further documented in the sql/database package.

Example Configuration

receivers:
  postgresql:
    endpoint: localhost:5432
    transport: tcp
    username: otel
    password: ${env:POSTGRESQL_PASSWORD}
    connection_pool:
      max_idle_time: 10m
      max_lifetime: 0
      max_idle: 2
      max_open: 5

Metrics

Details about the metrics produced by this receiver can be found in metadata.yaml

Metrics

Metric NameDescriptionUnitTypeAttributes
βœ… postgresql.backendsThe number of backends.1UpDownCounter
βœ… postgresql.bgwriter.buffers.allocatedNumber of buffers allocated.{buffers}Counter
βœ… postgresql.bgwriter.buffers.writesNumber of buffers written.{buffers}Counterbg_buffer_source
βœ… postgresql.bgwriter.checkpoint.countThe number of checkpoints performed.{checkpoints}Counterbg_checkpoint_type
βœ… postgresql.bgwriter.durationTotal time spent writing and syncing files to disk by checkpoints.msCounterbg_duration_type
βœ… postgresql.bgwriter.maxwrittenNumber of times the background writer stopped a cleaning scan because it had written too many buffers.1Counter
❌ postgresql.blks_hitNumber of times disk blocks were found already in the buffer cache.{blks_hit}Counter
❌ postgresql.blks_readNumber of disk blocks read in this database.{blks_read}Counter
βœ… postgresql.blocks_readThe number of blocks read.1Countersource
βœ… postgresql.commitsThe number of commits.1Counter
βœ… postgresql.connection.maxConfigured maximum number of client connections allowed{connections}Gauge
βœ… postgresql.database.countNumber of user databases.{databases}UpDownCounter
❌ postgresql.database.locksThe number of database locks.{lock}Gaugerelation, mode, lock_type
βœ… postgresql.db_sizeThe database disk usage.ByUpDownCounter
❌ postgresql.deadlocksThe number of deadlocks.{deadlock}Counter
❌ postgresql.function.callsThe number of calls made to a function. Requires track_functions=pl|all in Postgres config.{call}Counterfunction
βœ… postgresql.index.scansThe number of index scans on a table.{scans}Counter
βœ… postgresql.index.sizeThe size of the index on disk.ByGauge
βœ… postgresql.operationsThe number of db row operations.1Counteroperation
βœ… postgresql.replication.data_delayThe amount of data delayed in replication.ByGaugereplication_client
βœ… postgresql.rollbacksThe number of rollbacks.1Counter
βœ… postgresql.rowsThe number of rows in the database.1UpDownCounterstate
❌ postgresql.sequential_scansThe number of sequential scans.{sequential_scan}Counter
βœ… postgresql.table.countNumber of user tables in a database.{table}UpDownCounter
βœ… postgresql.table.sizeDisk space used by a table.ByUpDownCounter
βœ… postgresql.table.vacuum.countNumber of times a table has manually been vacuumed.{vacuum}Counter
❌ postgresql.temp.ioTotal amount of data written to temporary files by queries.ByCounter
❌ postgresql.temp_filesThe number of temp files.{temp_file}Counter
❌ postgresql.tup_deletedNumber of rows deleted by queries in the database.{tup_deleted}Counter
❌ postgresql.tup_fetchedNumber of rows fetched by queries in the database.{tup_fetched}Counter
❌ postgresql.tup_insertedNumber of rows inserted by queries in the database.{tup_inserted}Counter
❌ postgresql.tup_returnedNumber of rows returned by queries in the database.{tup_returned}Counter
❌ postgresql.tup_updatedNumber of rows updated by queries in the database.{tup_updated}Counter
βœ… postgresql.wal.ageAge of the oldest WAL file.sGauge
❌ postgresql.wal.delayTime between flushing recent WAL locally and receiving notification that the standby server has completed an operation with it.sGaugewal_operation_lag, replication_client
βœ… postgresql.wal.lagTime between flushing recent WAL locally and receiving notification that the standby server has completed an operation with it.sGaugewal_operation_lag, replication_client

Attributes

Attribute NameDescriptionTypeValues
sourceThe source of a buffer write.stringbackend, backend_fsync, checkpoints, bgwriter
typeThe type of checkpoint state.stringrequested, scheduled
typeThe type of time spent during the checkpoint.stringsync, write
db.namespaceThe namespace or schema of the database where the query is executed.string
db.query.textThe text of the database query being executed.string
db.system.nameThe database management system (DBMS) product as identified by the client instrumentation.stringpostgresql
functionThe name of the function.string
lock_typeType of the lockable object.string
modeName of the lock mode held or desired by the process.string
network.peer.addressIP address of the client connected to this backend.string
network.peer.portTCP port number that the client is using for communication with this backend.int
operationThe database operation.stringins, upd, del, hot_upd
postgresql.application_nameName of the application that is connected to this backend.string
postgresql.callsNumber of times the statement was executed, reported in delta value.int
postgresql.client_hostnameHost name of the connected client, as reported by a reverse DNS lookup of client_addr.string
postgresql.pidProcess ID of this backend.int
postgresql.query_idIdentifier of this backend’s most recent query. If state is active this field shows the identifier of the currently executing query. In all other states, it shows the identifier of last query that was executed.string
postgresql.query_planThe execution plan used by PostgreSQL for the query.string
postgresql.query_startTime when the currently active query was started, or if state is not active, when the last query was started.string
postgresql.queryidHash code to identify identical normalized queries.string
postgresql.rolnameThe name of the PostgreSQL role that executed the query.string
postgresql.rowsTotal number of rows retrieved or affected by the statement, reported in delta value.int
postgresql.shared_blks_dirtiedTotal number of shared blocks dirtied by the statement, reported in delta value.int
postgresql.shared_blks_hitTotal number of shared block cache hits by the statement, reported in delta value.int
postgresql.shared_blks_readTotal number of shared blocks read by the statement, reported in delta value.int
postgresql.shared_blks_writtenTotal number of shared blocks written by the statement, reported in delta value.int
postgresql.stateCurrent overall state of this backendstring
postgresql.temp_blks_readTotal number of temp blocks read by the statement, reported in delta value.int
postgresql.temp_blks_writtenTotal number of temp blocks written by the statement, reported in delta value.int
postgresql.total_exec_timeTotal time spent executing the statement, in delta milliseconds.double
postgresql.total_plan_timeTotal time spent planning the statement, in delta milliseconds.double
postgresql.wait_eventWait event name if backend is currently waiting, otherwise NULL.string
postgresql.wait_event_typeThe type of event for which the backend is waiting, if any; otherwise NULL.string
relationOID of the relation targeted by the lock, or null if the target is not a relation or part of a relation.string
replication_clientThe IP address of the client connected to this backend. If this field is β€œunix”, it indicates either that the client is connected via a Unix socket.string
sourceThe block read source type.stringheap_read, heap_hit, idx_read, idx_hit, toast_read, toast_hit, tidx_read, tidx_hit
stateThe tuple (row) state.stringdead, live
user.nameName of the user logged into this backend.string
operationThe operation which is responsible for the lag.stringflush, replay, write

Resource Attributes

Attribute NameDescriptionTypeEnabled
postgresql.database.nameThe name of the database.stringβœ…
postgresql.index.nameThe name of the index on a table.stringβœ…
postgresql.schema.nameThe schema name.stringβœ…
postgresql.table.nameThe table name.stringβœ…
service.instance.idA unique identifier of the PostgreSQL instance in the format host:port (defaults to β€˜unknown:5432’ in case of error in generating this value).stringβœ…

Configuration

Example Configuration

postgresql/minimal:
  endpoint: localhost:5432
  username: otel
  password: ${env:POSTGRESQL_PASSWORD}
  top_query_collection:
    top_n_query: 1234
    query_plan_cache_ttl: 123s
postgresql/pool:
  endpoint: localhost:5432
  transport: tcp
  username: otel
  password: ${env:POSTGRESQL_PASSWORD}
  connection_pool:
    max_idle_time: 30s
    max_idle: 5
postgresql/all:
  endpoint: localhost:5432
  transport: tcp
  username: otel
  password: ${env:POSTGRESQL_PASSWORD}
  databases:
    - otel
  exclude_databases:
    - template0
  collection_interval: 10s
  tls:
    insecure: false
    insecure_skip_verify: false
    ca_file: /home/otel/authorities.crt
    cert_file: /home/otel/mypostgrescert.crt
    key_file: /home/otel/mypostgreskey.key
  connection_pool:
    max_idle_time: 30s
    max_lifetime: 1m
    max_idle: 5
    max_open: 10

Last generated: 2026-04-13