CLI tool
microsoft/krabsetw avatar
microsoft/krabsetw

krabsetw: a C++ and .NET wrapper for Windows ETW trace consumption

KrabsETW provides a modern C++ wrapper and a .NET wrapper around the low-level ETW trace consumption functions.

809 stars167 forksC++NOASSERTION

At a glance

What is it?
krabsetw is a C++ library from Microsoft that wraps the low level Event Tracing for Windows consumption API so a client can enable traces and providers and register for event notifications, with a C++ CLI .NET wrapper called Microsoft.O365.Security.Native.ETW that the Office 365 Security team uses in production. It suits a Windows developer who needs to consume ETW events in C++ or .NET, and it is a poor fit if you need to write ETW providers or run on anything other than x64 or ARM64 Windows.
Who is it for?
krabsetw suits a Windows developer who has to consume ETW events from C++ or .NET, since the wrapper covers trace and provider enablement, notification registration and parsing of generic event data into typed values, and the .NET package is already running in production inside the Office 365 Security team.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 13 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Consuming ETW without writing the C API by hand

krabsetw is a C++ library that simplifies interacting with ETW. It allows for any number of traces and providers to be enabled and for client code to register for event notifications from these traces.

ETW, Event Tracing for Windows, is the tracing infrastructure Windows has had for a long time, and it is the mechanism behind the diagnostics that the platform itself produces. Consuming it from a program means dealing with a low level C API: session and provider handles, buffers, callbacks, and a fair amount of lifecycle management.

The library wraps that. The two capabilities the README names are the ones that matter in practice. The first is that any number of traces and providers can be enabled, which is what you need when you are merging several log sources into one consumer. The second is that client code can register for event notifications, so the program receives events as they are written rather than pulling a buffer later.

The third capability, which the README lists separately, is code to simplify parsing generic event data into strongly typed data types. ETW delivers events with a schema rather than a fixed structure, and a consumer that wants a typed value has to look up the property and convert it. Doing that by hand for every field of every event is the part of ETW that is tedious enough that people give up, and the library exists to take it away.

The project is hosted by Microsoft, the primary language is C++, and the last push to the repository was on 2026-10-10 with no GitHub releases published, so you build against the source or against the NuGet packages rather than against a tagged version.

Lobsters is the .NET face of the same library

The second half of the project is the one most .NET developers will actually use.

Microsoft.O365.Security.Native.ETW is a C++ CLI .NET wrapper around krabsetw. It provides the same functionality as krabsetw to .NET applications, and it is used in production by the Office 365 Security team. It is affectionately referred to as Lobsters.

The architecture behind that is worth understanding. The .NET assembly is not a reimplementation, it is a wrapper over the same native library, so the C++ code remains the single source of behaviour and the .NET layer is a binding. The repository makes that visible in the directory layout, with the krabs directory holding the native library, the Microsoft.O365.Security.Native.ETW directory holding the managed wrapper, and a separate Microsoft.O365.Security.Native.ETW.NetCore directory for the .NET Core build.

There is a second reason to know this. The .NET wrapper is a mixed mode library, C++ CLI, which means it targets the .NET Framework runtime rather than being a purely managed assembly, and that is why the NuGet section includes a separate package for the headers and a Debug package that provides type asserts.

The stated production use is a reasonable signal about the level of care in the code, and the fact that the library is a first party Microsoft project with a public issue tracker means the usual question of who answers the issue tracker has an answer.

Four constraints that shape any design built on it

The Important Notes section of the README is short and each line changes what you can do with the library.

First, krabsetw and Microsoft.O365.Security.Native.ETW only support x64 and ARM64, and no effort has been made to support x86. That is a hard platform floor, and it also means the 32 bit toolchain and the 32 bit runtime are not on the roadmap for anyone.

Second, both are only supported on Windows 7 or Windows 2008R2 machines and above. So the library is not portable to Linux or macOS, and it is not going to run on the Windows versions that Microsoft stopped supporting.

Third, and this is the one that will shape your error handling: throwing exceptions in the event handler callback will cause the trace to stop processing events. The callback runs inside the trace processing path, so an exception does not just fail one event, it stops the stream.

Fourth, the call to start on the trace object is blocking, so thread management may be necessary. A consumer that starts a trace has to plan for the fact that the call does not return until the trace stops.

The third and fourth notes together are the whole operational story of the library. A notification callback has to be written so that it cannot throw, and the start call has to be moved off your main thread or onto a thread you control, because it is a long running operation wearing the shape of a function call.

Native builds carry a compilation flag warning

There is one build detail that has bitten people before, and the README points at it directly.

When building a native code binary using the krabsetw package, the compilation readme is the place to look, for notes about the TYPEASSERT and NDEBUG compilation flags.

This is the same pair of flags that appear in the NuGet package list, because the Debug package exists specifically to provide type asserts. A release build compiled with NDEBUG defined will not perform the type assertions that a debug build performs, and a native consumer that was tested against the debug package can behave differently from the same code in a release build.

That is a classic and quiet class of problem, and the fact that the package ships a separate Debug variant with type asserts is a good sign that the maintainers thought about it. The NuGet list has three entries for this reason, the Microsoft.O365.Security.Native.ETW package, the Microsoft.O365.Security.Native.ETW.Debug package for development which provides type asserts, and the Microsoft.O365.Security.Krabsetw package for the C++ headers.

The build tooling in the repository reflects a C++ and .NET mixed project, with a Visual Studio solution at krabs\krabs.sln, a PowerShell script for generating reference assemblies, a global.json, a strong name key file, and the nuspec files for each package. The global.json in particular suggests the build pins its .NET SDK version, which is how a repository with both native and managed components stays reproducible.

Verifying the managed binaries with the strong name utility

The README includes one verification recipe, and it is a good habit to copy for any native component you take from a package feed.

For verifying the .NET binaries, you can use the following command.

bash
sn -T Microsoft.O365.Security.Native.ETW.dll

And the expected output is this.

code
Microsoft (R) .NET Framework Strong Name Utility  Version 4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.

Public key token is 31bf3856ad364e35

The public key token is the interesting line, because it is a short fingerprint of the signing identity. If the token in your downloaded assembly does not match, the package is not the one the project published, and the difference between two builds that both claim to be the same library is exactly the kind of thing that matters when the library is parsing security telemetry.

The strong name key file in the repository root, 35MSSharedLib1024.snk, is the matching piece on the build side, and the fact that a shared key file is committed to a public repository is a well known property of strong naming, which authenticates identity and not integrity.

For a security focused consumer, the more substantial check is the one the project itself models: use the C++ and .NET examples in the examples directory, which include managed examples, native examples and a schema key collision reproduction case. That last one is worth a look, because it suggests the authors have hit the failure mode where two event schemas collide on a key, which is the sort of edge that only appears with real world providers.

The primer is where the actual learning is

The documentation list in the README is where a new user should start, and it is a reading list rather than a manual.

There is an ETW Primer at docs/EtwPrimer.md, which is the sensible starting point if ETW itself is new to you, because krabsetw assumes you already know what a provider is and what a trace session does. Then there are two example documents, KrabsExample.md and LobstersExample.md, one per language binding, and simple examples in the examples folder. A separate document covers using Message Analyzer to find new ETW event sources, which is the practical answer to the question every consumer eventually asks, namely how you discover what is traceable on a machine you did not write.

There is also SampleKrabsCSharpExe, described as a non-trivial example demonstrating how to manage the trace objects, and that phrase is worth taking seriously. The trivial example is a callback that prints an event. The non-trivial one is about lifecycle, and the lifecycle of a trace is where the interesting decisions live, given that start blocks and that an exception in a callback stops the stream.

The repository also carries a SECURITY.md alongside the CONTRIBUTING.md, and the community section says to file issues through GitHub for bugs and feature requests, and that the maintainers will respond as quickly as they are able.

One gap the README does not fill is versioning. There are no GitHub releases, so there is no tag to pin, and the .NET package version and the C++ header version can move independently. For a library you link into a native or managed binary, that is a practical thing to sort out in your own build rather than inherit from the package feed.

Editorial conclusion

krabsetw suits a Windows developer who has to consume ETW events from C++ or .NET, since the wrapper covers trace and provider enablement, notification registration and parsing of generic event data into typed values, and the .NET package is already running in production inside the Office 365 Security team. It does not suit a project that needs to define ETW providers, and it does not suit 32 bit x86 or non Windows targets, since the README says only x64 and ARM64 are supported and that no effort has been made to support x86. Before you build on it, read the ETW primer and the two example documents, plan for the two documented failure modes, since an exception thrown in an event handler stops event processing and the start call on a trace object is blocking, and note the licence is recorded as a custom one with the LICENSE file in the repository root as the document to read.

Frequently asked questions

What is krabsetw?

It is a C++ library that simplifies interacting with ETW, allowing any number of traces and providers to be enabled and letting client code register for event notifications from those traces. It also provides code to simplify parsing generic event data into strongly typed data types.

What is Microsoft.O365.Security.Native.ETW?

It is a C++ CLI .NET wrapper around krabsetw that gives .NET applications the same functionality, and it is used in production by the Office 365 Security team. The project refers to it affectionately as Lobsters.

Which platforms does krabsetw support?

The README states that krabsetw and Microsoft.O365.Security.Native.ETW only support x64 and ARM64, with no effort made to support x86, and that both are only supported on Windows 7 or Windows 2008R2 machines and above.

What happens if an exception is thrown inside an ETW event handler?

The README states that throwing exceptions in the event handler callback will cause the trace to stop processing events, so a handler that can throw stops the whole stream rather than failing one event.

How do I verify the .NET binaries from krabsetw?

The README gives the command sn -T Microsoft.O365.Security.Native.ETW.dll, and says the expected output is the Strong Name Utility version line, the Microsoft copyright line, and the public key token 31bf3856ad364e35.

Official sources

  1. Issues
  2. microsoft/krabsetw on GitHub
  3. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/microsoft-krabsetw.svg)](https://hysenlabs.com/projects/microsoft-krabsetw)

Was this useful?