Skip to content

Instantly share code, notes, and snippets.

@kstrauss
Last active December 14, 2021 01:28
Show Gist options
  • Save kstrauss/01e06ca61f2b6b09fd9c to your computer and use it in GitHub Desktop.
Save kstrauss/01e06ca61f2b6b09fd9c to your computer and use it in GitHub Desktop.
Example of publishing simple ETW events (no manifest and therefore EventLog) and consuming them in a realtime fashion
All need the Microsoft.Diagnostics.Tracing.TraceEvent nuget package
Shows how you can both produce some simple ETW events (these are not written to the eventlog)
A couple of ways to consume said events.
1. using standard tooling like perfview, xperf, etc.
2. create your own EventListener class as demonstrated by ProducerAndSimpleListener, which allows you to do pretty much anything
3. listen in realtime as done in RealTimeListener
4. Others do similar things I believe like tx.windows
/*
Attempts to use event source and write to etw
https://code.msdn.microsoft.com/windowsapps/Logging-Sample-for-Windows-0b9dffd7
seems to indicate that you use an EventListener to intercept the logging
messages and devert them somewhere else beside ETW
*/
void Main()
{
//new Listener();//.EnableEvents(MinimalEventSource.Log, EventLevel.LogAlways);
for (int i = 0; i< 10; i++){
MinimalEventSource.Log.Load("Linqpad Sample");
Thread.Sleep(TimeSpan.FromSeconds(7));
}
MinimalEventSource.Log.Unload("Linqpad Sample");
}
public void OnNext(Tx.Windows.EtwNativeEvent value){
value.Dump("From Tx");
}
[EventSource(Name="AllEventSources")]
public sealed class AllEventSources : EventSource{
}
// Not sure why this attribute seems to cause things with PerfView not to work
// Having it there it doesn't see a provider of Samples* nor does it see one with *MinimalEventSource
// Removing it, it sees *MinimalEventSource - not sure what's going on
//[EventSource(Name="Samples-EventSourceDemos-Minimal")]
public sealed class MinimalEventSource : EventSource
{
public void Load(string imageName) {
Console.WriteLine("Writting loadevent");
WriteEvent(1, imageName);}
public void Unload(string imageName) { WriteEvent(2, imageName);}
protected override void OnEventCommand(EventCommandEventArgs command){
base.OnEventCommand(command);
command.Dump("Command");
}
public static MinimalEventSource Log = new MinimalEventSource();
}
public class Listener : EventListener{
protected override void OnEventSourceCreated(EventSource eventSource){
base.OnEventSourceCreated(eventSource);
eventSource.Dump("Loaded eventsource");
EnableEvents(eventSource, EventLevel.LogAlways);
}
protected override void OnEventWritten(EventWrittenEventArgs eventData){
eventData.Dump("Wrote event");
}
}
//a simple listener as based on http://blogs.msdn.com/b/vancem/archive/2012/12/20/and-end-to-end-etw-tracing-example-eventsource-and-traceevent.aspx
void Main()
{
var sessionName = "test";
// Today you have to be Admin to turn on ETW events (anyone can write ETW events).
if (!(TraceEventSession.IsElevated() ?? false))
{
Console.WriteLine("To turn on ETW events you need to be Administrator, please run from an Admin process.");
return;
}
using (var session = new Microsoft.Diagnostics.Tracing.Session.TraceEventSession(sessionName,null))
{
session.StopOnDispose = true;
// By default, if you hit Ctrl-C your .NET objects may not be disposed, so force it to. It is OK if dispose is called twice.
Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e) { session.Dispose(); };
using (var source = new ETWTraceEventSource(sessionName, TraceEventSourceType.Session)){
"Creating source".Dump();
var parser = new DynamicTraceEventParser(source);
session.EnableProvider("MinimalEventSource",TraceEventLevel.Always);
parser.All += (te)=>{if (te.EventName != "ManifestData"){ te.Dump("From All");}};
source.Process();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment