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
Consolidate and clean up all API logging #15737
Consolidate and clean up all API logging #15737
Conversation
`s_TraceApi` was a magic function in Tracing that logged a different event based on what type it was called with. It was bad for two reasons: 1. I wanted to add a field to each trace indicating the originating process and thread. This would have required adding a `CONSOLE_API_MSG` parameter to _every instance_ of `s_TraceApi`, and even then it would have not been particularly consistent. 2. The design of Tracing, where the TraceLogging macros are hidden inside opaque functions, subverts the lightweight trace probe detection present in `TraceLoggingWrite`. Every tracing probe turned into a call to a cold function which, in 99% of cases, returned immediately. To that end, I've introduced a new macro _only_ to ApiDispatchers that emits a named probe with a set of preloaded information. It is a macro to avoid any unnecessary branching or the emission of any explicit tracing functions into the final binary. I have also removed the generic handler for timing any/all API calls, as we never used them and they were largely redundant with the information we were capturing from API-specific reports. I've also removed tracing from all APIs that do not mutate console state. With the notable exception of ReadConsoleInput, we will see logs only for things that change mutable console state. All these things together allows us to construct a process+API-focused timeline of console events, ala: ``` cmd.exe (20304) CookedRead pwsh 4 07/13/2023 22:02:53.751 cmd.exe (20304) API_GetConsoleMode True cmd.exe (20304) API_SetConsoleMode False 0x00000003 cmd.exe (20304) API_SetConsoleMode True 0x000001F7 pwsh.exe (4032) ConsoleAttachDetach 07/13/2023 22:03:17.393 True True pwsh.exe (4032) API_GetConsoleMode False pwsh.exe (4032) API_GetConsoleMode False pwsh.exe (4032) API_SetConsoleMode False 0x00000007 ```
They were originally using uint32/64, which did not allow for tools like WPA to infer their connection to processes and dates. I cleared this with David Kaplan, as he is relying on those events.
src/server/ApiDispatchers.cpp
Outdated
TraceLoggingWrite( \ | ||
g_hConhostV2EventTraceProvider, \ | ||
"API_" ApiName, \ | ||
TraceLoggingPid([&] { const auto p=m->GetProcessHandle(); return p ? p->dwProcessId : 0; }(), "OriginatingProcess"), \ |
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 could be lifted out if reviewers desire.
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 personally would prefer that. This will produce a unique lambda instance per macro invocation which then might get folded into a single instance in Release builds if the compiler realizes they're all the same assembly. But I believe it's safer if we add free-standing TraceGetProcessId
and TraceGetThreadId
functions instead that take a CONSOLE_API_MSG*
and put them above the macro. It would also make compilation a teeny tiny bit cheaper.
(We could also add them as member functions to CONSOLE_API_MSG
, but I would greatly prefer if we moved CONSOLE_API_MSG
back to being a trivial class. I'm really not sure if the "writing data off the end of the class" thing is legal C++ when the struct is non-trivial and I'd rather not tempt fate. 😓)
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 switched to functions. Trust me, the CONSOLE_API_MSG
class gives me the ABSOLUTE willies
src/server/ApiDispatchers.cpp
Outdated
TraceLoggingInt32(a->CurrentWindowSize.X, "WindowWidthInChars"), | ||
TraceLoggingInt32(a->CurrentWindowSize.Y, "WindowHeightInChars"), |
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.
nit 1: These have a different name than the actual fields.
nit 2: Technically these are Int16 right? We can improve the way COORD
s are formatted in traces if we use TraceLoggingStruct
here. If we add a new macro like TraceLoggingConsoleCoord
that abstracts this away, I think it might look pretty neat. Something like
#define TraceLoggingConsoleCoord(value, name) \
TraceLoggingStruct(2, name), \
TraceLoggingInt16(value.X, "X"), \
TraceLoggingInt16(value.Y, "Y")
Alternatively, we could also use TraceLoggingInt16FixedArray(&a->CurrentWindowSize, "CurrentWindowSize")
.
nit 3: People depend on our trace logs and we can't change their names? 😟
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.
Ugh, these names, types and values were ported directly from the original tracing.cpp
code. We can definitely change them. I like T.L.Struct.
The only logs people are depending on are CookedRead
and ConsoleAttachDetach
. The rest, we can blow up any way we wish.
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.
DONE LOOKS GREAT
`s_TraceApi` was a magic function in Tracing that logged a different event based on what type it was called with. It was bad for two reasons: 1. I wanted to add a field to each trace indicating the originating process and thread. This would have required adding a `CONSOLE_API_MSG` parameter to _every instance_ of `s_TraceApi`, and even then it would have not been particularly consistent. 2. The design of Tracing, where the TraceLogging macros are hidden inside opaque functions, subverts the lightweight trace probe detection present in `TraceLoggingWrite`. Every tracing probe turned into a call to a cold function which, in 99% of cases, returned immediately. To that end, I've introduced a new macro _only_ to ApiDispatchers that emits a named probe with a set of preloaded information. It is a macro to avoid any unnecessary branching or the emission of any explicit tracing functions into the final binary. I have also removed the generic handler for timing any/all API calls, as we never used them and they were largely redundant with the information we were capturing from API-specific reports. I've also removed tracing from all APIs that do not mutate console state. With the notable exception of ReadConsoleInput, we will see logs only for things that change mutable console state. All these things together allows us to construct a process+API-focused timeline of console events, ala: ``` cmd.exe (20304) CookedRead pwsh 4 07/13/2023 22:02:53.751 cmd.exe (20304) API_GetConsoleMode True cmd.exe (20304) API_SetConsoleMode False 0x00000003 cmd.exe (20304) API_SetConsoleMode True 0x000001F7 pwsh.exe (4032) ConsoleAttachDetach 07/13/2023 22:03:17.393 True True pwsh.exe (4032) API_GetConsoleMode False pwsh.exe (4032) API_GetConsoleMode False pwsh.exe (4032) API_SetConsoleMode False 0x00000007 ``` This pull request also switches the ConsoleAttachDetach and CookedRead reports to use the PID and FILETIME markings for their pids and filetimes. This is compatible with the uint32 and uint64 fields that used to use those names, so anybody who was depending on them will experience no change in functionality. I also switched up their order to make them more ergonomic in WPA when combined with the other API_ tracing (as viewed above.) (cherry picked from commit 5daf498) Service-Card-Id: 90012630 Service-Version: 1.17
`s_TraceApi` was a magic function in Tracing that logged a different event based on what type it was called with. It was bad for two reasons: 1. I wanted to add a field to each trace indicating the originating process and thread. This would have required adding a `CONSOLE_API_MSG` parameter to _every instance_ of `s_TraceApi`, and even then it would have not been particularly consistent. 2. The design of Tracing, where the TraceLogging macros are hidden inside opaque functions, subverts the lightweight trace probe detection present in `TraceLoggingWrite`. Every tracing probe turned into a call to a cold function which, in 99% of cases, returned immediately. To that end, I've introduced a new macro _only_ to ApiDispatchers that emits a named probe with a set of preloaded information. It is a macro to avoid any unnecessary branching or the emission of any explicit tracing functions into the final binary. I have also removed the generic handler for timing any/all API calls, as we never used them and they were largely redundant with the information we were capturing from API-specific reports. I've also removed tracing from all APIs that do not mutate console state. With the notable exception of ReadConsoleInput, we will see logs only for things that change mutable console state. All these things together allows us to construct a process+API-focused timeline of console events, ala: ``` cmd.exe (20304) CookedRead pwsh 4 07/13/2023 22:02:53.751 cmd.exe (20304) API_GetConsoleMode True cmd.exe (20304) API_SetConsoleMode False 0x00000003 cmd.exe (20304) API_SetConsoleMode True 0x000001F7 pwsh.exe (4032) ConsoleAttachDetach 07/13/2023 22:03:17.393 True True pwsh.exe (4032) API_GetConsoleMode False pwsh.exe (4032) API_GetConsoleMode False pwsh.exe (4032) API_SetConsoleMode False 0x00000007 ``` This pull request also switches the ConsoleAttachDetach and CookedRead reports to use the PID and FILETIME markings for their pids and filetimes. This is compatible with the uint32 and uint64 fields that used to use those names, so anybody who was depending on them will experience no change in functionality. I also switched up their order to make them more ergonomic in WPA when combined with the other API_ tracing (as viewed above.) (cherry picked from commit 5daf498) Service-Card-Id: 90012631 Service-Version: 1.18
s_TraceApi
was a magic function in Tracing that logged a differentevent based on what type it was called with. It was bad for two reasons:
process and thread. This would have required adding a
CONSOLE_API_MSG
parameter to every instance of
s_TraceApi
, and even then it wouldhave not been particularly consistent.
inside opaque functions, subverts the lightweight trace probe detection
present in
TraceLoggingWrite
. Every tracing probe turned into a callto a cold function which, in 99% of cases, returned immediately.
To that end, I've introduced a new macro only to ApiDispatchers that
emits a named probe with a set of preloaded information. It is a macro
to avoid any unnecessary branching or the emission of any explicit
tracing functions into the final binary.
I have also removed the generic handler for timing any/all API calls, as
we never used them and they were largely redundant with the information
we were capturing from API-specific reports.
I've also removed tracing from all APIs that do not mutate console
state. With the notable exception of ReadConsoleInput, we will see logs
only for things that change mutable console state.
All these things together allows us to construct a process+API-focused
timeline of console events, ala:
This pull request also switches the ConsoleAttachDetach and CookedRead
reports to use the PID and FILETIME markings for their pids and
filetimes. This is compatible with the uint32 and uint64 fields that
used to use those names, so anybody who was depending on them will
experience no change in functionality.
I also switched up their order to make them more ergonomic in WPA when
combined with the other API_ tracing (as viewed above.)