Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: support OpenTelemetry metrics #1465

Conversation

hengfengli
Copy link
Collaborator

@hengfengli hengfengli commented Feb 26, 2024

Add two latency metrics:

  • spanner/pgadapter/roundtrip_latencies: measure the roundtrip latency in PGAdapter that can include multiple messages between the client and PGAdapter.
  • spanner/pgadapter/client_lib_latencies: measure the time to make a request and get a response from the client library.

pom.xml Outdated Show resolved Hide resolved
@@ -98,6 +110,16 @@ public BackendConnection getBackendConnection() {
return backendConnection;
}

public static Attributes getMetricAttributes(DatabaseId databaseId) {
AttributesBuilder attributesBuilder = Attributes.builder();
if (databaseId != null) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

databaseId should never be null (at least not for a real connection, maybe in some tests it is). Could we therefore change this into a more direct implementation, where:

  1. metricAttributes are always created when ExtendedQueryProtocolHandler is created.
  2. This method is not static, but an instance method, and always just returns the actual metricAttributes of this ExtendedQueryProtocolHandler. It should also not take DatabaseId (or anything else) as an input argument, as the DatabaseId is fixed for an ExtendedQueryProtocolHandler. The structure here is that:
  3. Each connection from a client to PGAdapter has one ConnectionHandler.
  4. There is a one-to-one relationship between ConnectionHandler and ExtendedQueryProtocolHandler.
  5. There is a one-to-one relationship between ExtendedQueryProtocolHandler and BackendConnection.
  6. All of the above classes also have exactly one DatabaseId that never changes during their lifetime.

Now it seems like metricAttributes sometimes needs to be created on-the-fly, but I don't think that is ever true.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I was originally creating metricAttributes in ExtendedQueryProtocolHandler and pass it to the BackendConnection. But I thought we already pass databaseId into it in here. I need to construct the attributes in Execute of BackendConnection.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also think databaseId should not be null but I add this check due to an error. If I add metricAttributes as an instance method, can the Execute of BackendConnection access it? Let me explore it more.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please take a look my latest changes. Basically, I need the attributes in Execute of BackendConnection.

@hengfengli
Copy link
Collaborator Author

@olavloite , currently, client_lib_latencies only covers execute_on_spanner but execute_batch_on_spanner is not included. Do we want to include execute_batch_on_spanner in client_lib_latencies as well?

@hengfengli hengfengli changed the title chore: support latency metrics chore: support OpenTelemetry metrics Feb 28, 2024
Simplify OpenTelemetry code by moving the Tracer and Metrics to
BackendConnection. This reduces the need to manage the same objects in
multiple places, and reduces the number of places where arguments need
to be added to existing methods.
@olavloite
Copy link
Collaborator

@hengfengli I took the liberty of doing a small refactor of the code in order to simplify things a bit. I think it is better if we only keep the tracer and metrics in one place (BackendConnection). In addition, we do not need to create a new Metrics instance for each connection, as it does not have any connection-specific state. Instead, one instance per ProxyServer is enough.

@olavloite
Copy link
Collaborator

@olavloite , currently, client_lib_latencies only covers execute_on_spanner but execute_batch_on_spanner is not included. Do we want to include execute_batch_on_spanner in client_lib_latencies as well?

Yes, that should be included as well. execute_batch_on_spanner is the same as ExecuteBatchDml (and UpdateDatabaseDdlRequest with multiple DDL statements, but that is less relevant here).


PGAdapter supports Open Telemetry tracing. You can enable this by adding the `-enable_otel` command
line argument when starting PGAdapter.
PGAdapter supports OpenTelemetry tracing and metrics. You can enable the tracing or the metrics
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
PGAdapter supports OpenTelemetry tracing and metrics. You can enable the tracing or the metrics
PGAdapter supports OpenTelemetry tracing and metrics. You can enable tracing or metrics

Comment on lines +155 to +156
* `spanner/pgadapter/client_lib_latencies`: Latency when the Spanner's client library receives
a call and returns a response.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* `spanner/pgadapter/client_lib_latencies`: Latency when the Spanner's client library receives
a call and returns a response.
* `spanner/pgadapter/client_lib_latencies`: Latency between the Spanner client library receiving
a request and returning a response.

GoogleCloudMetricExporter.createWithConfiguration(
MetricConfiguration.builder()
// Configure the cloud project id.
.setProjectId(projectId)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs a null check, as projectId can be null, and .setProject will throw a NullPointerException if the project is null.

projectId is null if PGAdapter has been started without a specific project on the command line.

@olavloite olavloite merged commit 1ed11f9 into GoogleCloudPlatform:postgresql-dialect Mar 4, 2024
34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants