Friday, February 17, 2012

Conditional WPP Tracing with WPP_LEVEL_ENABLED

In general WPP tracing is a no-op if tracing is not enabled on your component.  For instance, you don't need to worry about if this line is making your production code slower when tracing is not enabled:

LogTrace(MY_ERROR_LEVEL, L"Failed to start the RPC subsystem. hr = 0x%08x", hr);

But, there are times when you would like to trace something more involved than capturing an error and HRESULT.

For instance in this code, I wanted to be able to trace what SIDs I was generating, so to trace the string of the SID, some memory needed to be allocated.  I didn't want this to happen in my production code if tracing wasn't enabled.



LPWSTR pszSid = NULL;


if (!ConvertSidToStringSid(pTokenGroups->Groups[i].Sid, &pszSid)) {
    LogTrace(DAS_ERROR_LEVEL, "Could not generate SID string 0x%x\n", HRESULT_FROM_WIN32(GetLastError()));
}
else {
    LogTrace(DAS_INFO_LEVEL, "Created process SID %ls\n", (LPCWSTR)pszSid);
}


if (pszSid) {
    LocalFree(pszSid);
}


Sure, the LogTrace is a no-op if tracing isn't enabled, but I will always be allocating the string regardless.  I didn't want that in my production code.  This is where the WPP_LEVEL_ENABLED macro comes in.

WPP_LEVEL_ENABLED(level) can check to see if a certain level is currently enabled.  It is generated by the preproccessor, and uses the same mechanism the other WPP generated functions use to decided when to actually do work.

So, to fix that code snip:


if (WPP_LEVEL_ENABLED(MY_INFO_LEVEL) || WPP_LEVEL_ENABLED(MY_ERROR_LEVEL)) {
    LPWSTR pszSid = NULL;


    if (!ConvertSidToStringSid(pTokenGroups->Groups[i].Sid, &pszSid)) {
        LogTrace(MY_ERROR_LEVEL, "Could not generate SID string 0x%x\n", HRESULT_FROM_WIN32(GetLastError()));
    }
    else {
        LogTrace(MY_INFO_LEVEL, "Created process SID %ls\n", (LPCWSTR)pszSid);
    }


    if (pszSid) {
        LocalFree(pszSid);
    }
}

Now ConvertSidToStringSid will not be called and the string will not be allocated unless the component's WPP info level or error level is enabled.

Use this macro then to programmatically skip work that is only needed for WPP logging when logging isn't turned on.

No comments:

Post a Comment