Filtering WPP tracing per device?

I’m doing some WPP tracing in my driver, but want to filter tracing by device instance so I don’t get interleaved messages for all installed device instances.
Does anyone have any tips/suggestions for doing such a thing?

IFR is an add-on to WFP that lets you create & manage your own trace buffers. One of its explict design goals is to solve the situation you described above: you have a number of objects, and you want each to have their own independent set of traces. For example, you might have a chatty component, and you don’t want his traces to overrun the buffer of the other components. So IFR is organized around allocating a separate buffer for each component. Take a look and see if it’s attractive to you: https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/using-wpp-recorder

If you want to stick with vanilla WPP and not go through IFR, you can still structure things a bit to help de-interleave traces. What I’ve seen be pretty successful is to simply get into a habit of putting “Adapter=%p” in all traces, so that you can run a quick regex on the decoded text log to select a single adapter.

If the casual informality of that convention bothers you, you can make this stricter by creating a custom WPP macro that requires a component context handle as a parameter. For example:

// In your trace config header:

// Create a new macro named "DevTrace" that takes a device context as its 1st arg:
//begin_wpp config
//FUNC DevTrace(DEVCONTEXT,MSG,...);
//USEPREFIX(DevTrace, "[DeviceId=%u]", wppDeviceContext->MyId);
//end_wpp

// We want the trace callsite to look like this:
//    do {
//        MY_DEVICE_CONTEXT *wppDeviceContext = (<DEVCONTEXT argument>);
//        WppTrace("[DeviceId=%u]" "<rest of trace message>", wppDeviceContext->MyId, <other trace args>)
//    ; } while (0)
//
// The following two macros stich that together:

#define WPP_DEVCONTEXT_PRE(context) do { \
    MY_DEVICE_CONTEXT *wppDeviceContext = (context); \

#define WPP_DEVCONTEXT_POST(context) ; } while (0)

// In your driver code:

struct MY_DEVICE_CONTEXT {
    . . .
    ULONG MyId;
};

MY_DEVICE_CONTEXT *context = . . .;
. . .
DevTrace(context, "Something happened: %!status!, ntStatus);

This is a fantastic response. Thank you Mr. Tippet!