-
Notifications
You must be signed in to change notification settings - Fork 545
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
feat(instrumentation-pg): add post-query custom attributes hook for spans #767
feat(instrumentation-pg): add post-query custom attributes hook for spans #767
Conversation
This comment has been minimized.
This comment has been minimized.
1 similar comment
|
This comment has been minimized.
This comment has been minimized.
/easycla |
Codecov Report
@@ Coverage Diff @@
## main #767 +/- ##
==========================================
- Coverage 94.88% 93.13% -1.76%
==========================================
Files 13 10 -3
Lines 684 888 +204
Branches 138 94 -44
==========================================
+ Hits 649 827 +178
- Misses 35 61 +26 |
@Alon-Katz You'll need to rebase your PR against main |
f24b996
to
27a4050
Compare
@vmarchaud Sorry for the delay, I have rebased against main. |
@rauno56 could you take the time to review this PR ? |
I apologize for missing this one, @Alon-Katz. 20 days is really an unacceptable delay for a review. This is no doubt an useful feature. Not only for pg but potentially every other instrumentation. What kind of custom attributes are you looking to add to the spans from pg, @Alon-Katz? |
@rauno56 Judging from the fact that the PR has been opened from https://github.com/epsagon (which is an apm product) i guess they want to have more metadata to display. |
Sure, I was asking to validate whether it could be done somewhere else in the pipeline. It's a functionality commonly asked for - it doesn't scale well to add post-hooks to each of the instrumentations. |
There has been multiple discussions across different instrumentations to do this on the instrument base, the problem is that you generally want instrumentation specific context so using SpanProcessor isn't viable. While no one took the work to add this kind of mechanism on instrumentation base its okay for me to let people add those hooks in each instrumentation |
What to you mean by instrumentation specific context? If I understand you correctly, I can only come up with
|
Not every information is available as span attributes, for example one might want to add remote server version but we don't have it by default. I don't think its scalable to try add all data by default and let people use span processors. Specially since vendor might want other kind of data that we didn't think of. |
We agree on that - There has to be a mechanism for vendors or users to add their own attributes and this PR solves for that in the context of However, now that we've seen the same feature added into different instrumentations with somewhat different semantics or ergonomics again and again we should know better. I think merging this does more harm than good long term and support solving this in a more general manner instead. Do you think there's an usecase we cannot support by making it a general feature? |
I agree that we need to make it a general feature, but i don't agree with refusing PRs because contributors don't have the time to make a generic system. cc @dyladan if you could give your opinion on this to see what to do here |
I think as a feature it makes sense. There will always be information that people want to add to the spans with additional context that is not available at the span processor level. @rauno56 is the owner of this module and I think he should have the final decision. When we decided to give ownership of modules to the contributors who maintain them, the original idea was that they would have the final say in decisions like this unless there was a security concern or similar extenuating circumstance. My personal suggestion would be to accept the feature because there is currently no generic system and the feature provides value, but ultimately the decision is Rauno's. Creating a generic system for this feature might be difficult because of all the different types of modules involved, but maybe we could at least make the configurations consistent across instrumentations that hook similar modules. For example, all the DB instrumentations would probably benefit from the same hooks with consistent naming. It might make sense for us to make our own document in this repo which describes a set of suggested hooks for each type of module? |
Yes, that makes sense actually, @vmarchaud. My bad. @Alon-Katz, could you please enable "Allow edits from maintainers" so we wouldn't be stuck with the branch being out of date with the base branch. In conclusion, I'd love to merge this for now with the hope to replace it with something more general in the long run. I do not understand, however, why do you find it difficult to make something more general? |
Simply because of the wide variety of modules that need to be instrumented and the resulting variety of useful hook points and their arguments. Maybe its easier than I'm thinking. |
I don't think there is a lot of hidden complixity in this (not saying its trivial though) but we all have limited time to allocate and this wasn't a priority in the past (specially with the GA of api/sdk). There was discussion for a more generic instrumentation API that might have specified how to handle generic configuration like this (open-telemetry/opentelemetry-js#2359), so generally we might want to have a complete API for instrumentation before trying to implement this feature in the base instrumentation class |
@rauno56 I followed the link for "Allow edits from maintainers", but for some reason it seems like I do not have this option. According to the documentation, the option should be in the right section below the notifications, this is how it looks on my side: |
@Alon-Katz Most likely the problem is because the repo you use is not your personal fork, it seems to be a fork from an organization. For such forks it's not working to allow maintainers to edit via this checkbox. So either move to a private fork in future PRs or take the burden to merge master regularly... I think @dyladan found some rest call from github to enable this for a single branch/PR even on org forks. |
You can do it with cURL:
|
Thanks! I ran the command, hopefully it works. |
|
@Alon-Katz seems like your CLA is signed for the Cisco email, but one of the commits(07924d6) is done from an Epsagon email address. That's why EasyCLA is probably upset. I'll review the PR on Monday. |
} | ||
|
||
export interface PgPostQueryHookFunction { | ||
(ctx: QueryContext): void; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please change the hook signature to follow the other hook example in this file:
export interface PgInstrumentationExecutionResponseHook {
(span: api.Span, responseInfo: PgResponseHookInformation): void;
}
First parameter should be the span.
Second parameter is called Info
on the other hook. Could be nice in my opinion to call it queryInfo
(to stay consistent with the existing name.
From what I remember, this is also the convention in other instrumentations.
assert.strictEqual(ctx.query, query); | ||
assert.strictEqual(ctx.params, undefined); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These assertions are performed in the hook body.
I think that if they fail, the exception will just be silently ignored and test will pass.
That is because the hook is protected with safeExecuteInTheMiddle which does not propagate exceptions to the caller.
} | ||
}); | ||
assert.strictEqual(called, true); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also suggest having some negative tests for the hook - what happens if it throws? what if it's not a function?
This introduced new logic is currently not covered with tests.
You can see an example of that on the responseHook tests here
@@ -563,5 +563,113 @@ describe('pg', () => { | |||
client.query('SELECT NOW()').then(queryHandler); | |||
}); | |||
}); | |||
|
|||
it('should call postQueryHook with query text if set', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can wrap this section with a describe
to group all these tests under postQueryHook
.
This will also be consistent with the existing tests for responseHook
see here
Hi @Alon-Katz |
Hi @blumamir, thanks for time you put into making the CR but unfortunately I will not have the time to continue this PR at the moment, I will close it. |
Which problem is this PR solving?
Short description of the changes