-
Notifications
You must be signed in to change notification settings - Fork 480
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
Implement session::get_last_query_context() #1164
base: master
Are you sure you want to change the base?
Conversation
d2cc2a8
to
6798c27
Compare
6798c27
to
c5d67dd
Compare
@vadz do you think we need a way to disable parameter logging? Compared to the overhead of the actual DB query the logging of parameters is likely insignificant but maybe you have a scenario in mind in which this might become important? |
75848e5
to
5f5702e
Compare
The only 2 potential problems I can think about are:
But it looks like both could be addressed by overriding |
Yes. Also, parameters are not logged persistently. They only live to the next query execution. That is still not good for sensitive information of course. Just wanted to clarify. |
Just to be explicit about it: from my POV this PR is done |
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.
Thanks for your work on this, but after rereading it carefully, I've realized that, in addition to various small remarks below, I have a more global question (and I'm really sorry for completely missing your question about this originally): with this change we now impose some extra overhead for all queries, even if it's not needed at all. Granted, this overhead is not huge, but I'm not sure it's completely negligible neither, considering that there may be a lot of parameters in a query (I'm sure I have some with a few dozens in my own code). Have you tried to measure it by chance?
I don't know if we can avoid this by only returning the query context on demand, i.e. only when/if logger::get_last_query_context()
is called, but it looks like it should be possible, or am I missing some reason it isn't?
In any case, after we decide on their final shape, the new APIs need to be mentioned in at least docs/api/client.md
and docs/logging.md
(we probably need to have a new section about logging parameter values in the latter).
Thanks again!
src/core/session.cpp
Outdated
std::string name; | ||
std::string value; |
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.
Not that important, but I'd make this change
std::string name; | |
std::string value; | |
const std::string name; | |
const std::string value; |
to be explicit about the fact that they never change.
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 think here is the wrong place to do this. This should be encoded in the place that actually uses an instance of this struct by making that specific instance const
.
Additionally, having const members can have unintended side-effects like a disabled (by default) assignment operator. That's why I usually don't like having const
members 🤔
I don't think we have access to the last executed statement, do we? And without access to that, how do you want to obtain the last used parameters?
I didn't measure it. My gut tells me that any DB call will take significantly longer than logging a tens, even hundreds of parameters but that's just guessing. I was thinking of whether there might be a semantic such as
to have a way to explicitly toggle the behavior to opt in or out of this feature. |
@vadz what do you think of the above suggestion? |
Sorry for the delay, I still didn't have time to look at this properly, but maybe you can answer my question without spending any time on it: Could we store a pointer to the statement being executed in the session? Or do we need to get the query context after the statement has been already destroyed? |
I think we do need this functionality. Imo the context is most useful when young some sort of error handling (for the error message) and at this point the executed statement is usually destroyed already (as to my understanding the statement only lives until it has been executed). |
But couldn't we fill the context in |
I don't think so. When we use the rethrow, we are still within the statement (which is therefore still alive). However, we need to be able to access the context even when the statement has already been destroyed (as we want to be able to access the context whenever we access the last query, which is independent of the statement object). And also, we don't want to have the context available only when there is an error while executing the statement. |
I thought we could fill the context stored in the session, but do it only when an exception happens. What prevents us from doing it? This doesn't help if we want to have the context even without the exception, of course, but IME this is mostly useful when an error occurs, logging successful executions doesn't seem very interesting... But, in principle, we could also pass some enum class LogContext
{
Never,
Always,
OnError
}; to |
I disagree. There are soft errors that arise from the semantics which happen even though the query was successful. In fact, this is the primary use case for me as the exception message in case of a DB error already contains the parameters.
Works for me 👍 |
Would you be willing to implement this |
Yes absolutely! I just didn't find the time to do so yet. |
No problem at all, I just wanted to check if you were waiting for something from me. |
Fixes #678
Fixes #1027