-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Context propagation for query logging #7596
Comments
Duplicate of #6882 |
If you ignore the middleware aspect of this that you assumed @Sytten, this is essentially about e.g. creating a query id (or request id) and logging that with each query, so any external tooling can pick those out of the logs and correlate Prisma Client query to logged SQL query. |
Possibly also duplicate of #6519 and #5956 Would assume it shouldn't really depend on which tracing solution is used, but the end result should be queries being traced which are as well correlated to the trigger on prisma client side (and furthermore the root of the prisma client call -> API Request, Background Job, etc). |
same issue + 1 |
Hi, having the same issue. |
Its already on the roadmap of prisma https://www.notion.so/Support-Tracing-in-Prisma-Client-c0afd7599022435da2b8fc05c30cd1c0 |
@tak1n this doesn't require tracing support in Prisma, per se. The issue is that since Prisma queries are sent to a rust engine, all of the context from the A simple solution would be to have callbacks that run synchronously on the client side, prior to sending the request to rust and after receiving the response, running within the context of our GQL resolver or REST endpoint. Instead, our only way with the existing API today is to observe the query via an asynchronous [inter process] RPC. This is a feature request to have middleware in the client that wraps the outbound request to Rust, allowing us to log not only the request/response but also the surrounding context like Instead, what we have today is a notification from Rust that it received an inbound request (at which point the context surrounding the original request we sent is lost) A workaround would be for me to wrap my Prisma client to "decorate" the behavior by wrapping each of the method calls in |
I tried this approach: prisma.$use(async (params, next) => {
return await tracer.trace('prisma.query', async (span) => {
span?.setTag('model', params.model);
span?.setTag('action', params.action);
span?.setTag('runInTransaction', params.runInTransaction);
logger.debug('Prisma query', {
model: params.model,
action: params.action,
runInTransaction: params.runInTransaction,
});
const result = await next(params);
return result;
});
}); The spans are also taken out of context of the parent span from where I sent my Prisma query. try {
throw new Error();
} catch (e) {
console.log(e);
} the above debug logging shows the stack trace lost the context that I called my prisma query from a particular GQL resolver / file:
In my opinion the proposal from @matthewmueller in #6882 (comment) doesn't have anything to do with solving this issue. I do not want to manually get the parent span and pass it into every Prisma query. If I was willing to accept that boilerplate, I could just wrap every prisma query callsite in a span manually. What I really want is I just want the middleware to run from within the context where I called my Prisma query. I also noticed if the middleware throws an error, the query never resolves or rejects and it causes the upstream http request to never respond. Seems like middleware are not useful (for this use case) or production ready (errors will never be surfaced or logged). |
Can you please make sure an issue with more information for this exists? Thanks. |
i've discovered that if you use the binary query engine instead of the default Node-API based one, then the async context is not lost in the it would be nice if the docs would talk a little more about the differences between those engines. the only thing it really says is "The Node-API library approach is recommended since it reduces the communication overhead between the Prisma Client and the query engine." but that makes me wonder why the binary engine is even an option at this point? |
Because sometimes the Node-API library gets something wrong, that works fine with the binary engine. Then it is a temporary workaround to use the binary engine. It is not recommended to use in other cases, and might be removed at any time. |
@janpio would you consider this loss of async context an instance of the Node-API library getting something wrong? if so, can it be fixed? or is there some fundamental limitation with the Node-API approach that will never allow this to work? i still don't really understand why the query event handler gets invoked in a different async context than that which initiated the prisma query (especially since it's only the case with the Node-API engine but not with the binary engine) |
Right now we do not give any expectation that the async context would be kept - it is not part of our documented API -, which is why this feature request exists and tracks this expectation (or other solutions to achieve the same outcome). So right now this seems to be undefined to me. If you really need it, you can use the binary to work around that - but be aware that you are off the really recommended path then and might have other negative (or positive) effects that are not documented. |
I tried to use the binary to work around that but it does not really work.
The clsService return undefined. My prisma engine was loaded with binary ✔ Generated Prisma Client (4.15.0 | binary) to ./node_modules/@prisma/client in 553ms any idea? |
Hi @janpio, I really want to contribute to that. I commented above and the solution you suggested has not worked, how can I contribute to the project, or have a solution for that |
Have you managed to make it work? |
@EladIsraeli sorry i missed your question until now. i've been away from this problem for long enough now that i don't recall the details, but i recall a few things that might help you here if you're still stuck and still wanting to work around it with the binary engine. i was using the |
This is a perfect summary by @joshribakoff-sm. In short
One workaround I found is using the Prisma preview feature that allows the use of native Node.js database driver adapters to perform queries instead of the Prisma engine. Because these database adapters are executed in Node.js, You can find an example using https://github.com/brianc/node-postgres in |
Problem
Currently query logs can not relate to requests or a parent context from which they were invoked from. This means solutions like https://github.com/iamolegga/nestjs-pino or as well datadog tracing DataDog/dd-trace-js#1244 are not able to work properly.
Suggested solution
Context propagation into query logging should work properly. Sadly I'm quite new to nodejs and therefore aren't able to further specify how this should happen. Also not sure if the architecture of prisma is a blocker here (separate query engine process, and whether this gets simpler once n-api is used)
Alternatives
I've looked at https://github.com/Jeff-Lewis/cls-hooked (which nestjs-pino uses under the hood) so not a real alternative, but tried to understand whats happening here.
Additional context
Slack convo: https://prisma.slack.com/archives/CA491RJH0/p1623345269439900
The text was updated successfully, but these errors were encountered: