This change updates the logrus hook to sort the incoming logrus data
before passing it to the tracelogging code. This is useful because it
ensures that two instances of the same event have the fields in the same
order, which is necessary to get WPA to line the fields up.
This change adds support for encoding time.Time values as FILETIME
values in tracelogging events. FILETIME has slightly less precision than
time.Time (100ns vs 1ns), but it is the closest availble match.
The ETW registration handle is defined to be 64-bits on all platforms. The Go
type previously used a uintptr which created problems on 32-bit systems. This
change adds a new wrapper file which receives a 64-bit handle for the functions
defined in it, and correctly passes it to the native ETW functions either as-is
(on 64-bit) or as two 32-bit values (on 32-bit).
This required a minor change in mksyscall_windows.go, to allow multiple syscalls
that map to the same underlying function without causing a duplicate definition
error in the generated file.
Proper support for ETW on ARM will require additional changes in Go to support
more than 16 bytes of arguments to a syscall callback. Until this work is done,
the ETW package is being changed to no-op on ARM.
There is a cleanup function deferred to remove the provider from the global
provider map. However, this function didn't bind the value of provider ahead of
time, so when the provider creation returned with nil for provider, we tried to
cleanup a nil provider, and panicked.
ListenPipe can fail if there is a concurrent DialPipe because there is a
race window where DialPipe can connect to the initial server named pipe
before it is connected to and closed by ListenPipe.
To fix this, use the lower-level NT API for creating the server pipe,
since this API allows for specifying that a server pipe should initially
be in the disconnected state instead of the listening state. This allows
us to avoid the race condition by creating the pipe in the correct state
initially, so there is no longer a need to create a dummy client
connection.
Previously, the only constructor for the etwlogrus hook accepted a name, and
created a new ETW provider with that name. With this change, there is another
constructor which takes an already created ETW provider. This is to allow the
use of the ETW provider for other things, such as if the application wants to
support ETW capture state.
ETW and Logrus have similar, but different definitiosn of log level.
Originally, the plan was to just convert the integer value of the Logrus level
to an ETW level, and leave it at that. However, it turns out there are tools
that assume you are logging with the standard set of ETW log level. So now we
will map the Logrus level to an ETW level, so that these tools better.