Configuring EDB OTEL

The following configuration options are available with edb_otel.

Permissions

No permissions changes are required for edb_otel.

Prerequisites

The following prerequisites must be completed before using edb_otel to export metrics:

  • Set up an OpenTelemetry collector endpoint that edb_otel can communicate with. For detailed information on how to set up a quick test of the OpenTelemetry endpoint using Docker, see OTLP Exporter Example.
  • Install the pg_cron extension to schedule jobs for the pg_exporter.

GUCs

The following GUC variables are available in edb_otel.

Metrics GUCs

VariableDescriptionUnitDefaultMinimum value
edb_otel.metrics_endpointThe OTEL metrics endpoint URL.
edb_otel.intervalInterval between two consecutive exports. It translates to the OpenTelemetry metric reader parameter exportIntervalMillis.Milliseconds2 seconds1 second
edb_otel.timeoutHow long the export can run before it's canceled. It translates to the OpenTelemetry metric reader parameter exportTimeoutMillis.Milliseconds500 milliseconds100 milliseconds
edb_otel.worker_nap_timeDuration of background worker sleep time before it checks for metrics in the queue and processes them.Milliseconds2 seconds1 second
edb_otel.metrics_queue_sizeInterval between two consecutive exports. This is the maximum size of the metrics queue. If the queue reaches this size, any subsequent metrics are dropped until the queue is cleared while processing the metrics inside it.MB100100

Tracing GUCs

VariableDescriptionUnitDefaultMinimum value
edb_otel.enable_tracingBoolean - set to enable tracing.false
edb_otel.traces_endpointThe OTEL tracing endpoint URL.
edb_otel.traces_service_nameA value for the service.name resource attribute. The tracing environment inherits this value and associates it with all spans created under the environment.

Configuring to use from an SQL interface

To use the edb_otel extension from a SQL interface, in postgresql.conf:

  1. Set the parameter edb_otel.metrics_endpoint to point to the metrics collector endpoint. For example:

    edb_otel.metrics_endpoint='localhost:4317'
  2. Set the parameter edb_otel.traces_endpoint to point to the traces collector endpoint. For example:

    edb_otel.traces_endpoint='localhost:4317'
  3. Set the parameter edb_otel.enable_tracing to true enable tracing.

  4. Set the parameter edb_otel.tracing_service_name to the desired value for the service.name resource attribute.

  5. Add edb_otel to the shared_preload_libraries. For example:

    shared_preload_libraries = '$libdir/dbms_pipe,$libdir/edb_gen,$libdir/dbms_aq,$libdir/edb_otel'

Configuring to use in C code

Tracing support

The extension currently supports sending only metrics through C code. Support for traces will be added in a future release.

To use the edb_otel extension from your C code:

  1. Ensure the edb_otel_ext.h file is in reach of your extension at build time. The file is placed in $prefix/include/server/extension/edb_otel/ when the edb_otel dev/devel package is installed. Your makefile must add pg_config --includedir-server to its include search paths so your extension can use it as:

    #include "extension/edb_otel/edb_otel_ext.h"

    This header defines a structure that stores a list of pointers to functions which are used to send metrics to the OTEL endpoint. This list directly corresponds to the metric apis exposed in the SQL interface.

  2. When the edb_otel extension is loaded, it places an object of this structure in the rendezvous variable identified by "edb_otel_metric_func". So the next step is to fetch the object and report metrics using the callbacks it exposes:

    EdbOtel_plugin * edb_otel_plugin_ptr = NULL;
    edb_otel_plugin_ptr =
        *(EdbOtel_plugin **) find_rendezvous_variable("edb_otel_metric_func");

    You can store the structure pointer in a session-long variable, but take care in case edb_otel gets loaded after the calling code.

    Since the instrumented code must continue to work even when edb_otel isn't in use, if the function pointer returns NULL, no error should be raised, and the structure pointer must not be dereferenced.

    For example, instrumenting pg_stat_statements to send the number of plans can look similar to this:

    /* Report a metric of type GAUGE that has a floating point value */
    if (edb_otel_plugin_ptr) {
       (edb_otel_plugin_ptr->edb_otel_metric_func_type_d)
          ("pg_stat_statements",
          "plans",
          EDB_OTEL_GAUGE,
          e->counters.calls[PGSS_PLAN],
          labels);
    }

The edb_otel_metric_func_type_d() and edb_otel_metric_func_type_l() functions have the following parameters.

Parameter(s)Input or outputDescription
meter_nameInputA name to identify a group of metrics
metric_nameInputA name to identify an actual measurement of the metric
metric_typeInputIdentified by one of the values in the enum EdbOtelMetricType defined in edb_otel_ext.h
measurementInputuse edb_otel_metric_func_type_d() to report a floating point value and edb_otel_metric_func_type_l() to pass an integer value.
labelsInputA JSONB string representing additional metadata to be associated with the metric, for example, attaching the query text to the measurement of pg_stat_statements
Note

Take care when calling the function that sends metrics. It's important to avoid using it in hot paths and while holding locks, since it may perform non-trivial work, even if only pushing data through a shm_mq to a background worker.


Could this page be better? Report a problem or suggest an addition!