feat: postgresql responseHook support#528
Conversation
Codecov Report
@@ Coverage Diff @@
## main #528 +/- ##
========================================
Coverage 94.92% 94.93%
========================================
Files 162 159 -3
Lines 9991 9828 -163
Branches 992 932 -60
========================================
- Hits 9484 9330 -154
+ Misses 507 498 -9
|
|
Hey @obecny, fixed the commits issue (had to create a new PR), tnx! |
| @@ -199,6 +200,7 @@ export class PgInstrumentation extends InstrumentationBase { | |||
| .then((result: unknown) => { | |||
| // Return a pass-along promise which ends the span and then goes to user's orig resolvers | |||
| return new Promise(resolve => { | |||
There was a problem hiding this comment.
I understand that nested new Promise was here before but it really is not needed.
You can just do the sync calls inside the then callback function and it behaves exactly the same.
There was a problem hiding this comment.
thanks @rauno56, I agree and also noticed it when writing this PR. However, and if that is alright with you, I'd prefer to leave this change to a different PR?
|
Generally looks good! Thanks for the effort you've put into it and sorry for the late review! |
plugins/node/opentelemetry-instrumentation-pg/src/instrumentation.ts
Outdated
Show resolved
Hide resolved
plugins/node/opentelemetry-instrumentation-pg/src/instrumentation.ts
Outdated
Show resolved
Hide resolved
| import { InstrumentationConfig } from '@opentelemetry/instrumentation'; | ||
|
|
||
| export interface PgInstrumentationExecutionResponseHook { | ||
| (span: api.Span, data: pgTypes.QueryResult | pgTypes.QueryArrayResult): void; |
There was a problem hiding this comment.
Instead of sending data as the second parameter, it might be better to send an responseInfo with the data on it.
That way, when someone wants to add new parameters in the future, the function signature will not grow more and more.
There was a problem hiding this comment.
Good Idea! will change.
| }, | ||
| err => { | ||
| if (err) { | ||
| diag.error('Error running response hook', err); |
There was a problem hiding this comment.
optional: I like to add a prefix to my logs so if it prints, there is context on where it's coming from. Something like: pg instrumentation: ${...}
There was a problem hiding this comment.
Great idea, I’d suggest implementing this (in a separate PR, of course) at the InstrumentationBase level so that it won't be necessary to manually add the prefix separately for each instrumentation class. WDYT?
There was a problem hiding this comment.
I now read the v0.21.0 release notes and looks like it was added there:
open-telemetry/opentelemetry-js#2261
There was a problem hiding this comment.
It was indeed added on instrumentation but you should use this._diag from the instrumentation class to be able to use it. I think you'll need to give the instance class here to make it work
There was a problem hiding this comment.
@vmarchaud, @blumamir for this PR I recommend not adding this change.
_diag is a protected member, it's accessible only internally within the class or any class that extends it but not externally. Since the pg instrumentation uses the utils module, passing the instrumentation will not be enough and a refactor is needed here.
There was a problem hiding this comment.
Yes, I agree. We tried to refactor our instrumentations as well and bumped into the same issue, and decided not to use this component logger after all.
However, we made sure all the log prints are prefixed with ${packageName} instrumentation:, for example.
But I see there is no convention for the contrib instrumentations on that, so it's up to you.
There was a problem hiding this comment.
why not passing the component logger to the util class directly from class when you call the util method ? @blumamir @nata7che in worst scenario I would change the signature to be public from protected instead of trying to mimic the behaviour of component diag logger. But it should be possible to simply pass the logger from class to util
| pgResult: pgTypes.QueryResult | pgTypes.QueryArrayResult | unknown | ||
| ) { | ||
| if ( | ||
| config.enhancedDatabaseReporting && |
There was a problem hiding this comment.
why do you require truthy enhancedDatabaseReporting for calling responseHook?
There was a problem hiding this comment.
will be removed also in accordance to @rauno56's comment above
| 0 | ||
| ); | ||
| runCallbackTest(span, pgAttributes, events, unsetStatus, 2, 1); | ||
| assert.ok(result, 'pool.query() returns a promise'); |
There was a problem hiding this comment.
result here was already awaited, right? so it's not a promise, it's the actual response for the invocation. Not sure what this assertion is meant to test... (but I don't mind if it stays here as well).
| message: err.message, | ||
| }); | ||
| } else { | ||
| handleExecutionResult(instrumentationConfig, span, res); |
There was a problem hiding this comment.
Shouldn't we also call the response hook in the patchCallbackPGPool function below?
Probably not, as I see there are tests for that, but how come it works?
There was a problem hiding this comment.
The PgPool instrumentation added an additional patching to the pgPool.connect method, and uses the same query patching.
There was a problem hiding this comment.
I have to admit I'm not very familiar with this instrumentation and its behavior.
So in what cases is "patchCallbackPGPool" being called?
|
hey @rauno56! I'd love to get your approval if you don't have any further comments 🙏🏻 |
plugins/node/opentelemetry-instrumentation-pg/src/instrumentation.ts
Outdated
Show resolved
Hide resolved
| span: Span, | ||
| pgResult: pgTypes.QueryResult | pgTypes.QueryArrayResult | unknown | ||
| ) { | ||
| if (config.responseHook !== undefined && pgResult !== undefined) { |
There was a problem hiding this comment.
Same comment from the other "add responseHook", why explicitly only checking against undefined? Why not if (config.responseHook && pg...)
Or event better if (typeof config.responseHook === "function" && pg...)
There was a problem hiding this comment.
I think we should just have if (typeof config.responseHook === "function") if user adds hook we should always run it whether the pgResult is undefined or not as this is also some kind of information for someone. Preventing running this hook in such case will confuse user why the hook didn't run soo I would definitely remove it.
|
@obecny @MSNev @vmarchaud thanks for your approval 💪🏻 are we good to go ahead and merge? |
Which problem is this PR solving?
Short description of the changes
enhancedDatabaseReportingflag, safely use it to collect the data from the execution result