logo

NJP

Monitoring PostgreSQL with OpenTelemetry and Cloud Observability

Import · Sep 15, 2023 · article

Configure a Collector receiver

The Collector primarily consists of three components:

  1. Receivers collect data from data sources, either by push or pull.
  2. Processors operate on data between its point of collection and export, performing operations such as filtering or transformation.
  3. Exporters ship the data out of the Collector, whether that be to a simple local logging console or to a remote backend like Cloud Observability.

To get started, we must configure our postgresql receiver by editing the Collector configuration file found at ``/etc/otelcol-contrib/config.yaml. Our simple configuration file, in its entirety, looks like this:

receivers:
  postgresql:
    username: otel
    password: otelpassword


processors:
  batch:

exporters:
  logging:
    verbosity: detailed

service:
  pipelines:
    metrics:
      receivers: [postgresql]
      processors: [batch]
      exporters: [logging]

We have configured the postgresql receiver with the username and password we set up in PostgreSQL. We will use the standard batch processor

, which batches incoming data and compresses it for more efficient exporting.

Finally, we’ll use the logging exporter, which is configured with verbosity set to detailed. We’ll do this initially just to verify that the Collector is properly capturing metrics from PostgreSQL, but we’ll change our exporter later.

Next, we restart the Collector.

$ sudo systemctl restart otelcol-contrib 

To verify that the Collector is receiving metrics from our database, we run the following command:

$ journalctl -u otelcol-contrib -f 
... 
InstrumentationScope otelcol/postgresqlreceiver 0.68.0 
Metric #0 
Descriptor: 
     -> Name: postgresql.backends 
     -> Description: The number of backends. 
     -> Unit: 1 
     -> DataType: Sum 
     -> IsMonotonic: false 
     -> AggregationTemporality: Cumulative 
NumberDataPoints #0 
StartTimestamp: 2022-12-28 05:43:05.738132562 +0000 UTC 
Timestamp: 2022-12-28 05:43:35.772060409 +0000 UTC 
Value: 3 
Metric #1 
Descriptor: 
     -> Name: postgresql.commits 
     -> Description: The number of commits. 
     -> Unit: 1 
     -> DataType: Sum 
     -> IsMonotonic: true 
     -> AggregationTemporality: Cumulative 
NumberDataPoints #0 
StartTimestamp: 2022-12-28 05:43:05.738132562 +0000 UTC 
Timestamp: 2022-12-28 05:43:35.772060409 +0000 UTC 
Value: 159813 
Metric #2 
Descriptor: 
     -> Name: postgresql.db_size 
     -> Description: The database disk usage. 
     -> Unit: By 
     -> DataType: Sum 
     -> IsMonotonic: false 
     -> AggregationTemporality: Cumulative 
NumberDataPoints #0 
StartTimestamp: 2022-12-28 05:43:05.738132562 +0000 UTC 
Timestamp: 2022-12-28 05:43:35.772060409 +0000 UTC 
Value: 8168303 
... 

We’ve verified that the Collector is receiving metrics from PostgreSQL. Now, we’re ready to export those metrics to Cloud Observability.

After you’ve logged in, you can navigate to Project Settings, and then to the Access Tokens page. Create a new access token which your Collector will use for authentication when exporting its data to Cloud Observability.

Heather_Waters_0-1694709528729.png

Configure the Collector to export to Cloud Observability

Now that we have a Cloud Observability access token, we will need to modify our Collector configuration (found at /etc/otelcol-contrib/config.yaml). It should look like this:

receivers: 
  postgresql: 
    username: otel 
    password: otelpassword 

processors: 
  batch: 

exporters: 
  logging: 
    verbosity: detailed 
  otlp/lightstep 
    endpoint: ingest.lightstep.com:443 
    headers: {"lightstep-access-token": "INSERT YOUR TOKEN HERE"} 

service: 
  pipelines: 
    metrics: 
      receivers: [postgresql] 
      processors: [batch] 
      exporters: [otlp/lightstep] 

Please note: Cloud Observability continues to uselightstep

(the former product name) in code

for ongoing compatibility.

We’ve configured a new exporter, which we call otlp/lightstep. This otlp exporter uses the OpenTelemetry Protocol (OTLP); we give it a unique name for our use of the exporter by adding /lightstep to our exporter configuration. We use the standard endpoint, and we paste in our access token from the previous step.

Finally, we restart the Collector.

$ sudo systemctl restart otelcol-contrib 

Those are all of the steps we need to take on the Collector side. Now, we can move to Cloud Observability to start thinking about queries and alerts.

In this section, we’ll cover some basic usage of Cloud Observability. However, more detailed usage steps and examples can be found here.

Creating a dashboard

We can begin by creating a dashboard with charts of various PostgreSQL metrics that the Collector has captured. On the Dashboards page, click on Create Dashboard.

Heather_Waters_0-1694716677325.png

On the New Dashboard page, we can provide a name and a description for our dashboard.

Heather_Waters_1-1694716677325.png

Adding a chart

Next, we click on Add a chart. For the new chart, we provide a title for the chart. We can use the query builder to build a query around a specific metric or set of metrics.

Heather_Waters_2-1694716677326.png

With “Metric” selected, we can begin typing in the search box. We are shown suggestions that begin with postgresql, which show metrics that are coming through the Collector.

Heather_Waters_3-1694716755678.png

For example, we can choose postgresql.backends to plot the number of client connections to our PostgreSQL instance. After opening several terminals to make several connections to PostgreSQL, we begin to see data plotted like the following:

Heather_Waters_4-1694716865357.png

We can adjust the time range for our query. For example, we can adjust the chart to show the last 15 minutes.

Heather_Waters_5-1694716865358.png

The resulting chart looks like this:

Heather_Waters_6-1694716865358.png

Adding multiple metrics to a chart

We can add another metric to this chart, such as postgresql.connection.max.

Heather_Waters_7-1694716865359.png

The resulting chart now shows both metrics, with active connections in blue (all in the 6-10 connections range) and max connections in purple (fixed at 100).

Heather_Waters_8-1694717016866.png

Working with formulas

Although seeing the number of active connections and max connections is helpful, it would be more useful for us to see the proportion of active connections to max connections. For this, we continue working within the present cart, but we click on Add a formula.

Heather_Waters_9-1694717016866.png

The active connections metric is labeled (by Cloud Observability) as a, while the max connections metric is labeled as b. To express the percentage of our allowable connections that is currently active, we would write a formula like this:

Heather_Waters_10-1694717016867.png

Then, we toggle what our chart displays, showing only the resulting percentage value while hiding the raw metrics. We do this by checking the box for our formula but unchecking the boxes for metrics a and b.

Heather_Waters_11-1694717016867.png

The resulting chart looks like this:

Heather_Waters_12-1694717016867.png

Max connections is set to 100, therefore, an active connection count of eight will result in an active connections proportion of 8%. However, if we modify the configuration of our PostgreSQL instance to set the max connections to 20, our chart would look like this:

Heather_Waters_13-1694717016867.png

Quite quickly, our proportion of active connections jumps from around 4% (which is 4 out of 100) to 20% (which is 4 out of 20).

We change the type of our chart to show Area rather than Line, and then we rename our chart to “% of Connections Active.” Finally, we save our chart. Our dashboard, with one chart, now looks like this:

Heather_Waters_20-1694717277769.png

Adding multiple charts to a dashboard

After adding several charts, each with its own query, our dashboard begins to take shape.

Heather_Waters_21-1694717277770.png

Working with UQL in the Query Editor

Returning to our “% of Connections Active” query, you’ll recall how we originally used the Query Builder to create this query. If you’re familiar with UQL, you can also create your queries directly with the Query Editor. The equivalent of the query we created, in UQL, looks as follows:

Heather_Waters_22-1694717277771.png

Creating an alert

Lastly, we can also create alerts on our queries. Within our chart, we click on Create an alert.

Heather_Waters_23-1694717277771.png

We can configure our alert to trigger based on certain conditions related to our formula. For example, we can set a “critical threshold” at 80% of allowable connections active. We can also set a “warning threshold” at 60%.

Then, we can configure how Cloud Observability should notify us when these thresholds are reached. We can set up a notification to a generic webhook, Slack, or other destinations.

Heather_Waters_24-1694717277772.png

Conclusion

In this walkthrough, we guided you through the setup of the OpenTelemetry Collector to receive metrics from PostgreSQL and export them to Cloud Observability for querying, analysis, and alerting. Throughout this series, we’ll provide guides for connecting other components in your tech stack with the Collector and Cloud Observability.

Whether your organization is running a web application, an ML-backed data pipeline, or business-critical service integrations, you likely run PostgreSQL, and the performance and uptime of your PostgreSQL instances are essential to the success of your business. By monitoring key PostgreSQL metrics related to connections, resource usage, and transaction throughput, you can quickly detect and even preempt performance issues that might cripple your PostgreSQL-dependent systems and impact your operational efficiency.

For more information on what we’ve covered, check out the following resources:

View original source

https://www.servicenow.com/community/cloud-observability-blog/monitoring-postgresql-with-opentelemetry-and-cloud-observability/ba-p/2671951