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
Add context to config logger
property
#4230
Comments
@B4nan if you're interested in this, I'd be down to take a crack at it as my first real contribution 😅 |
Sounds a bit like you would like to generate a stack trace to get that information - that is slow and cannot be done on a query level, it would slow down things significantly.
Not sure what you mean by JSON format? Queries are strings, that is what gets executed. If you mean the object syntax for where queries, that is optional, and is handled on the QB level - the result is a string query and that is what gets executed, and I would definitely stick to that. I don't mind the idea of more context in the logger, but it would have to be without any perf hit, and I am not sure what you are proposing is what will be feasible - but slower things could be opt-in. I also don't think we need yet another logger instance, sounds a bit confusing to me. Not sure what you wanted to demonstrate in that example? :] Feel free to give it a try, you will probably have a better understanding of how it could look like once you dive deeper to the codebase. Maybe it would be enough to add some option to FindOptions and QB interface so its up to you to provide the context? I'd rather have more general approach for this, that allows you to do things your way. |
Here's an example of one of our queries: [query] select "i0"."id", "i0"."createdAt", "i0"."updatedAt", "i0"."host", "i0"."durationOption", "i0"."billing_hostHourlyRateInCents", "i0"."roomId", "i0"."billing_paymentIntentId", "i0"."billing_transferId", "i0"."billing_holdPayout", "i0"."status", "i0"."topic", "i0"."user", "h1"."id" as "h1__id", "h1"."createdAt" as "h1__createdAt", "h1"."updatedAt" as "h1__updatedAt", "h1"."user" as "h1__user", "h1"."handle" as "h1__handle", "h1"."displayName" as "h1__displayName", "h1"."title" as "h1__title", "h1"."aboutMe" as "h1__aboutMe", "h1"."expertise" as "h1__expertise", "h1"."stripeAccountId" as "h1__stripeAccountId", "h1"."avatarUrl" as "h1__avatarUrl", "h1"."socialUrls_Website" as "h1__socialUrls_Website", "h1"."socialUrls_Instagram" as "h1__socialUrls_Instagram", "h1"."socialUrls_Twitter" as "h1__socialUrls_Twitter", "h1"."socialUrls_YouTube" as "h1__socialUrls_YouTube", "h1"."socialUrls_Twitch" as "h1__socialUrls_Twitch", "h1"."socialUrls_LinkedIn" as "h1__socialUrls_LinkedIn", "h1"."socialUrls_Facebook" as "h1__socialUrls_Facebook", "h1"."socialUrls_TikTok" as "h1__socialUrls_TikTok", "h1"."socialUrls_Patreon" as "h1__socialUrls_Patreon", "h1"."isFeatured" as "h1__isFeatured", "h1"."referredBy" as "h1__referredBy", "c2"."id" as "c2__id", "c2"."createdAt" as "c2__createdAt", "c2"."updatedAt" as "c2__updatedAt", "c2"."host" as "c2__host", "c2"."title" as "c2__title", "c2"."description" as "c2__description", "c2"."status" as "c2__status", "c2"."position" as "c2__position", "c2"."interactionType" as "c2__interactionType", "c2"."isRecordedByDefault" as "c2__isRecordedByDefault", "c2"."schedulingPreferences_timezone" as "c2__schedulingPreferences_timezone", "c2"."schedulingPreferences_preferredTimes" as "c2__schedulingPreferences_preferredTimes", "c2"."hourlyRateInCents" as "c2__hourlyRateInCents", "d3"."id" as "d3__id", "d3"."createdAt" as "d3__createdAt", "d3"."updatedAt" as "d3__updatedAt", "d3"."callOption" as "d3__callOption", "d3"."lengthInMinutes" as "d3__lengthInMinutes", "d3"."discountPercent" as "d3__discountPercent", "d3"."isDefault" as "d3__isDefault", "d3"."status" as "d3__status", "u4"."id" as "u4__id", "u4"."createdAt" as "u4__createdAt", "u4"."updatedAt" as "u4__updatedAt", "u4"."email" as "u4__email", "u4"."firstName" as "u4__firstName", "u4"."lastName" as "u4__lastName", "u4"."phone" as "u4__phone", "u4"."acceptedTermsOfServiceVersion" as "u4__acceptedTermsOfServiceVersion", "u4"."acceptedPrivacyPolicyVersion" as "u4__acceptedPrivacyPolicyVersion", "u4"."status" as "u4__status", "u4"."host" as "u4__host" from "InstantMeeting" as "i0" left join "Host" as "h1" on "i0"."host" = "h1"."id" left join "CallOption" as "c2" on "h1"."id" = "c2"."host" left join "DurationOption" as "d3" on "c2"."id" = "d3"."callOption" left join "User" as "u4" on "i0"."user" = "u4"."id" where ("i0"."user" = '7' or "i0"."host" = '7') and "i0"."createdAt" >= '2023-02-16T16:15:55.928Z' order by "i0"."createdAt" desc [took 4 ms] (FYI that is the A->B->C entity I mentioned here) That's super, super unreadable... what I'd like to see is something like this: [query]: select Host, populate: 'durationOption.callOption', 'user'
where: {
createdAt: ">= '2023-02-16T16:15:55.928Z",
}
order by: 'createdAt desc'
Totally fair... what about a new property inside the const author = await em.findOneOrFail(Author, { id: 1 }, { populate: ['books'] }, { queryLabel: 'Author Middleware' });
// [query - Author Middleware]: ...
I was just trying to show off that it's kinda gross to try to handle sharing that context myself... I'd have to do it manually for all queries and make sure it's AFTER otherwise it'll get scrambled with the other async queries
haha we're on the same page... I submitted too quickly. I think that's a good approach... want to use |
I'd say this is really a matter of preference, and logging the exact query instead of this random format sounds like a better thing in general - this way you can clearly see what it generates and debug it further. It is a bit messy because you use joined strategy which selects all the columns explicitly.
I am definitely not adding another parameter after it - that is gross :] I'd rather see an option you can literally put anything in (so const author = await em.findOneOrFail(Author, { id: 1 }, {
populate: ['books'],
loggerContext: { queryLabel: 'Author Middleware' }, // can be a scalar too, not just an object
}); |
Oh 100%; I was saying that I would like that format if I had control over the logger, but I'm totally ok with the option to just add context; that helps enough
Hahaha well I guess I'll work on this this afternoon; I think it's best to start off with a limited type like what I have below and then add onto it; the label alone gets me 90% of what I'd want and that's likely to be a little different than adding additional properties in because the query label, IMO, should get tacked onto the type LoggerContext = string | {
queryLabel?: string
}; |
The thing before query is logger namespace, that is what you use to control what will be logged or not. I'd rather not make this “configurable”, but open for suggestions. Keep in mind there are more things we log, its not all about queries. |
Sounds good, I'll take a look and just make a draft before getting more feedback |
Is your feature request related to a problem? Please describe.
When logging information from the ORM, I would like to be able to see additional context surrounding the query
Describe the solution you'd like
I would like to be able to see additional information for a query when one is made; I want to see:
I doubt you want the extra details to get pumped into
console
so maybe anadvancedLogger
property on the config that has those extra properties and the other logger will be overridden if that property is provided.Describe alternatives you've considered
Adding log commands after queries have executed
Additional context
I tried adding my own little custom log commands AFTER queries (if you try before there's no way to guarantee it'll print with the related query if others are being executed at the same time) but it's kind of messy and isn't super scalable...
The text was updated successfully, but these errors were encountered: