Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@vonzshik
Copy link
Contributor

@vonzshik vonzshik commented Apr 7, 2025

Closes #4136

@vonzshik vonzshik requested a review from roji as a code owner April 7, 2025 14:54
Copy link
Member

@roji roji left a comment

Choose a reason for hiding this comment

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

@vonzshik this looks great - thanks, but let's maybe discuss whether the Activity should contain data source bootstrapping (and therefore type loading)?

_connectionLogger = dataSourceConfig.LoggingConfiguration.ConnectionLogger;
_commandLogger = dataSourceConfig.LoggingConfiguration.CommandLogger;

// Make sure we do not flow AsyncLocals like Activity.Current
Copy link
Member

Choose a reason for hiding this comment

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

👍

Though a part of me thinks we should maybe start the activity only after the data source has been set up - that really isn't part of physical connection open. What do you think?

// At no point should we ever have an activity here
Debug.Assert(Activity.Current is null);
// Set current activity as the one from the command
// So child activities from physical open are bound to it
Copy link
Member

Choose a reason for hiding this comment

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

Good thinking here.

Though at some point we should have the conversation about whether we want to keep multiplexing, given that it's known to be non-scalable (e.g. and is no longer used in the TE benchmarks).

LogMessages.OpeningPhysicalConnection(ConnectionLogger, Host, Port, Database, UserFacingConnectionString);
var startOpenTimestamp = Stopwatch.GetTimestamp();

var activity = NpgsqlActivitySource.ConnectionOpen(this);
Copy link
Member

Choose a reason for hiding this comment

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

As written below, there may be a case for only starting the activity after the data source is created and bootstrapped. Otherwise, the first "physical connection" is longer because it contains e.g. type loading and stuff like that; at minimum that skews stuff like average time calculations for physical open.

If we really wanted to surface startup costs like type loading properly, we could have another activity for that - though that seems like a bit much.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As written below, there may be a case for only starting the activity after the data source is created and bootstrapped. Otherwise, the first "physical connection" is longer because it contains e.g. type loading and stuff like that; at minimum that skews stuff like average time calculations for physical open.

I do not think anyone really calculates average time for any sort of traces (too much stuff to store), there are metrics specifically for stuff like this (for example, in Npgslq we have db.client.commands.duration). Beside, right now when we log physical open we pass the total time, including type loading.

If we really wanted to surface startup costs like type loading properly, we could have another activity for that - though that seems like a bit much.

This might actually be not a bad idea, since this will also allow us to trace NpgsqlConnection.ReloadTypes.

Copy link
Member

Choose a reason for hiding this comment

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

Right, makes sense. If it's not much work/changes, I'd try to exclude type loading from the activity span you're introducing here (simply because it really shouldn't be part of it). We can consider introducing a new activity for it, though I don't think that's very important.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, makes sense. If it's not much work/changes, I'd try to exclude type loading from the activity span you're introducing here (simply because it really shouldn't be part of it).

The main problem is that we do consider it a part of physical open. That is, if we get an exception during bootstrap or from DataSourceConnectionInitializer, we'll break the physical connection. In that case, should we pass that exception to activity? It would be really weird if we don't (since we'll throw the exception but the trace will be green, even though the connection is already closed). But then, that means that we can't close the activity until we're absolutely sure the connection is stable.

Copy link
Contributor Author

@vonzshik vonzshik Apr 8, 2025

Choose a reason for hiding this comment

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

Or to be more specific, we can specify Activity.Duration via Activity.SetEndTime, so while it's still be considered as active, the duration will remains as is, but IDK

Copy link
Member

Choose a reason for hiding this comment

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

I do not think anyone really calculates average time for any sort of traces (too much stuff to store), there are metrics specifically for stuff like this (for example, in Npgslq we have db.client.commands.duration). Beside, right now when we log physical open we pass the total time, including type loading.

FWIW calculating aggregate metrics from tracing data is a pretty standard thing to do, and indeed we could also not include the type loading time when logging.

But good point about the exception. I still think that fundamentally, type loading really shouldn't be counted as part of physical connection open; physical connections get opened all the time, whereas type loading is a one-time startup query that we happen to need (unless it's disabled by the user). It seems to just weirdly skew things to look at it as part of connection open.

But I'm OK with setting this aside for now and moving on - we can always change this in the future if we want.

@vonzshik vonzshik merged commit 251d73b into main Apr 9, 2025
14 checks passed
@vonzshik vonzshik deleted the 4136-trace-physical-open branch April 9, 2025 12:09
This was referenced Nov 23, 2025
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.

OpenTelemetry: instrument physical connection open/close

3 participants