Etw EventSourceProvider_EventsProducer.cs OopConsoleTraceEventListenerMonitor_TraceControllerEventsConsumer.cs

时间:2021-01-08 20:31:46


// EventSourceProvider_EventsProducer.cs
/*
/r:"D:\Microshaoft.Nuget.Packages\Microsoft.Diagnostics.Tracing.EventSource.Redist.1.1.28\lib\net46\Microsoft.Diagnostics.Tracing.EventSource.dll"
*/
namespace Test_EventSourceProvider_EventsProducer
{
using Microshaoft;
using Microshaoft.EventListeners;
using Microshaoft.EventSources;
using System;
using System.Diagnostics;
using System.IO;
using System.Security.Principal;
class Program
{
static void Main(string[] args)
{
Console.Title = Process.GetCurrentProcess().ProcessName;
// Deploy the app
var DeploymentFolder = Path
.Combine
(
Environment
.GetFolderPath
(
Environment
.SpecialFolder
.CommonApplicationData
)
, @"EventSourceSamples"
);
RegisterEventSourceWithOperatingSystemHelper
.SimulateInstall
(
@"D:\MyC#\EtwOk\EventSources\bin\Debug"
, DeploymentFolder
, EventLogEventSource.Log.Name
);
string input = string.Empty;
using (var listener = new ConsoleEventListener())
{
while ("q" != (input = Console.ReadLine()).Trim().ToLower())
{
EventLogEventSource
.Log
.WriteEvent1Log
(
1
, Guid.NewGuid()
, WindowsIdentity.GetCurrent().Name
, "这是一个测试 WriteEvent1Log"
);
EventLogEventSource
.Log
.WriteEvent2Log
(
2
, Guid.NewGuid()
, WindowsIdentity.GetCurrent().Name
, "这是一个测试 WriteEvent2 Log"
);
}
}
Console.ReadLine();
}
}
}
namespace Microshaoft.EventSources
{
using System;
using Microsoft.Diagnostics.Tracing;
//
// Shows how to use EventSouces to send messages to the Windows EventLog
//
// * EventLogEventSource
// * Uses the new 'Channel' attribute to indicate that certain events
// should go to the Windows Event Log. Note that the EventSource
// has to be registered with the Windows OS for this to work.
// In this example we send messages to the 'Admin' channel.
//
// * EventLogEventSourceDemo
// * simulates a deployment step needed to register the event source's
// manifest on the machine. If running unelevated it will prompt the user
// to allow running wevtutil.exe, the tool that performs the registration.
//
// * simulates processing multiple requests by calling the methods on
// EventLogEventSource to fire events.
// * pauses to allow the user to examine the event logs created under
// 'Application and Services Logs/Microsoft/EventSourceDemos/Channeled'
//
// * undoes the registration steps performed earlier.
//
[
EventSource
(
Name = "Microshaoft-EventLogEventSource-001" //"Samples-EventSourceDemos-EventLog"
)
]
public sealed class EventLogEventSource : EventSource
{
#region Singleton instance
public static EventLogEventSource Log = new EventLogEventSource();
#endregion
[
Event
(
1
, ActivityOptions = EventActivityOptions.None
, Channel = EventChannel.Admin
, Keywords = Keywords.EventKeyword1
//, Level = EventLevel.LogAlways
, Message =
@"
sequenceID : ""{0}""
, contextID : ""{1}""
, operatorID : ""{2}""
, data : ""{3}""
"
, Opcode = EventOpcode.Info
, Tags = EventTags.None
, Task = EventTasks.EventTask1
, Version = 1
)
]
public void WriteEvent1Log
(
int sequenceID
, Guid contextID
, string operatorID
, string data
)
{
WriteEvent
(
1
, (object)sequenceID
, (object)contextID
, (object)operatorID
, (object)data
);
}
[
Event
(
2
, ActivityOptions = EventActivityOptions.None
, Channel = EventChannel.Admin
, Keywords = Keywords.EventKeyword2
//, Level = EventLevel.LogAlways
, Message =
@"
sequenceID : ""{0}""
, contextID : ""{1}""
, operatorID : ""{2}""
, data : ""{3}""
"
, Opcode = EventOpcode.Info
, Tags = Tags.EventTag2
, Task = EventTasks.EventTask2
, Version = 1
)
]
public void WriteEvent2Log
(
int sequenceID
, Guid contextID
, string operatorID
, string data
)
{
WriteEvent
(
2
, (object)sequenceID
, (object)contextID
, (object)operatorID
, (object)data
);
}
#region Keywords / Tasks / Opcodes
public class Keywords // This is a bitvector
{
public const EventKeywords EventKeyword1 = (EventKeywords)0x00000001;
public const EventKeywords EventKeyword2 = (EventKeywords)0x00000002;
}
public class EventTasks
{
//[1,65534]
public const EventTask EventTask1 = (EventTask)1;
public const EventTask EventTask2 = (EventTask)2;
}
public class EventOpcodes
{
public const EventOpcode EventOpcode_0x0b = (EventOpcode)0x0b;
}
public class Tags
{
public const EventTags EventTag1 = (EventTags)1;
public const EventTags EventTag2 = (EventTags)2;
}
#endregion
}
}
namespace Microshaoft.EventListeners
{
using System;
using System.IO;
using System.Linq;
using Microsoft.Diagnostics.Tracing;
/// <summary>
/// An EventListener is the most basic 'sink' for EventSource events. All other sinks of
/// EventSource data can be thought of as 'built in' EventListeners. In any particular
/// AppDomain all the EventSources send messages to any EventListener in the same
/// AppDomain that have subscribed to them (using the EnableEvents API.
/// <para>
/// You create a particular kind of EventListener by subclassing the EventListener class
/// Here we create an EventListener that
/// . Enables all events on any EventSource-derived class created in the appDomain
/// . Sends all events raised by the event source classes created to the 'Out' textWriter
/// (typically the Console).
/// </para>
/// </summary>
public class ConsoleEventListener : EventListener
{
static TextWriter Out = Console.Out;
/// <summary>
/// Override this method to get a list of all the eventSources that exist.
/// </summary>
protected override void OnEventSourceCreated(EventSource eventSource)
{
// Because we want to turn on every EventSource, we subscribe to a callback that triggers
// when new EventSources are created. It is also fired when the EventListner is created
// for all pre-existing EventSources. Thus this callback get called once for every
// EventSource regardless of the order of EventSource and EventListener creation.
// For any EventSource we learn about, turn it on.
//Console.WriteLine(eventSource.GetType());
EnableEvents
(
eventSource
, EventLevel.LogAlways
, EventKeywords.All
);
}
/// <summary>
/// We override this method to get a callback on every event we subscribed to with EnableEvents
/// </summary>
/// <param name="eventData"></param>
protected override void OnEventWritten(EventWrittenEventArgs eventData)
{
// report all event information
Out.Write
(
" Event {0} "
, eventData.EventName
);
// Don't display activity information, as that's not used in the demos
// Out.Write(" (activity {0}{1}) ", ShortGuid(eventData.ActivityId),
// eventData.RelatedActivityId != Guid.Empty ? "->" + ShortGuid(eventData.RelatedActivityId) : "");
// Events can have formatting strings 'the Message property on the 'Event' attribute.
// If the event has a formatted message, print that, otherwise print out argument values.
if (eventData.Message != null)
{
Out.WriteLine
(
eventData.Message
, eventData.Payload != null
?
eventData.Payload.ToArray()
:
null
);
}
else
{
string[] sargs =
(
eventData.Payload != null
?
eventData
.Payload
.Select(o => o.ToString())
.ToArray()
:
null
);
Out.WriteLine("({0}).", sargs != null ? string.Join(", ", sargs) : "");
}
}
}
}
namespace Microshaoft
{
/// <summary>
/// For the Windows EventLog to listen for EventSources, they must be
/// registered with the operating system. This is a deployment step
/// (typically done by a installer). For demo purposes, however we
/// have written code run by the demo itself that accomplishes this
/// </summary>
using System;
using System.IO;
using System.Diagnostics;
using System.Threading;
public static class RegisterEventSourceWithOperatingSystemHelper
{
static TextWriter Out = Console.Out;
/// <summary>
/// Simulate an installation to 'destFolder' for the named eventSource. If you don't
/// specify eventSourceName all eventSources information next to the EXE is registered.
/// </summary>
public static void SimulateInstall
(
string sourceFolder
, string destFolder
, string eventSourceName = ""
, bool prompt = true
)
{
Out.WriteLine("Simulating the steps needed to register the EventSource with the OS");
Out.WriteLine("These steps are only needed for Windows Event Log support.");
Out.WriteLine("Admin privileges are needed to do this, so you will see elevation prompts");
Out.WriteLine("If you are not already elevated. Consider running from an admin window.");
Out.WriteLine();
if (prompt)
{
Out.WriteLine("Press <Enter> to proceed with installation");
Console.ReadLine();
}
Out.WriteLine("Deploying EventSource to {0}", destFolder);
// create deployment folder if needed
if (Directory.Exists(destFolder))
{
Out.WriteLine("Error: detected a previous deployment. Cleaning it up.");
SimulateUninstall(destFolder, false);
Out.WriteLine("Done Cleaning up orphaned installation.");
}
Out.WriteLine("Copying the EventSource manifest and compiled Manifest DLL to target directory.");
Directory.CreateDirectory(destFolder);
foreach (var filename in Directory.GetFiles(sourceFolder, "*" + eventSourceName + "*.etwManifest.???"))
{
var destPath = Path.Combine(destFolder, Path.GetFileName(filename));
Out.WriteLine("xcopy \"{0}\" \"{1}\"", filename, destPath);
File.Copy(filename, destPath, true);
}
Out.WriteLine("Registering the manifest with the OS (Need to be elevated)");
foreach (var filename in Directory.GetFiles(destFolder, "*.etwManifest.man"))
{
var commandArgs = string
.Format
(
"im {0} /rf:\"{1}\" /mf:\"{1}\""
, filename
, Path.Combine
(
destFolder
, Path.GetFileNameWithoutExtension(filename) + ".dll"
)
);
// as a precaution uninstall the manifest. It is easy for the demos to not be cleaned up
// and the install will fail if the EventSource is already registered.
var process = Process
.Start
(
new ProcessStartInfo("wevtutil.exe", "um" + commandArgs.Substring(2))
{
Verb = "runAs"
,
RedirectStandardOutput = true
,
UseShellExecute = false
}
);
Out.WriteLine(" wevtutil " + commandArgs);
Console.WriteLine
(
"wevtutil OUTPUT: {0}"
, process.StandardOutput.ReadToEnd()
);
process.WaitForExit();
Thread.Sleep(200); // just in case elevation makes the wait not work.
// The 'RunAs' indicates it needs to be elevated.
// Unfortunately this also makes it problematic to get the output or error code.
Out.WriteLine(" wevtutil " + commandArgs);
process = Process
.Start
(
new ProcessStartInfo("wevtutil.exe", commandArgs)
{
Verb = "runAs"
,
RedirectStandardOutput = true
,
UseShellExecute = false
}
);
Console.WriteLine
(
"wevtutil OUTPUT: {0}"
, process.StandardOutput.ReadToEnd()
);
process.WaitForExit();
}
Thread.Sleep(1000);
Out.WriteLine("Done deploying app.");
Out.WriteLine();
}
/// <summary>
/// Reverses the Install step
/// </summary>
public static void SimulateUninstall(string destFolder, bool prompt = true)
{
Out.WriteLine("Uninstalling the EventSoure demos from {0}", destFolder);
Out.WriteLine("This also requires elevation.");
Out.WriteLine("Please close the event viewer if you have not already done so!");
if (prompt)
{
Out.WriteLine("Press <Enter> to proceed with uninstall.");
Console.ReadLine();
}
// run wevtutil elevated to unregister the ETW manifests
Out.WriteLine("Unregistering manifests");
foreach (var filename in Directory.GetFiles(destFolder, "*.etwManifest.man"))
{
var commandArgs = string.Format("um {0}", filename);
Out.WriteLine(" wevtutil " + commandArgs);
// The 'RunAs' indicates it needs to be elevated.
var process = Process.Start(new ProcessStartInfo("wevtutil.exe", commandArgs) { Verb = "runAs" });
process.WaitForExit();
}
Out.WriteLine("Removing {0}", destFolder);
// If this fails, it means that something is using the directory. Typically this is an eventViewer or
// a command prompt in that directory or visual studio. If all else fails, rebooting should fix this.
if (Directory.Exists(destFolder))
{
Directory.Delete(destFolder, true);
}
Out.WriteLine("Done uninstalling app.");
}
}
}
// OopConsoleTraceEventListenerMonitor_TraceControllerEventsConsumer.cs
/*
# Microshaoft
/r:System.Xaml.dll
/r:System.Activities.dll
/r:System.Activities.DurableInstancing.dll
/r:System.Runtime.DurableInstancing.dll
/r:"D:\Microshaoft.Nuget.Packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll"
/r:"D:\Microshaoft.Nuget.Packages\Microsoft.Diagnostics.Tracing.EventSource.Redist.1.1.28\lib\net46\Microsoft.Diagnostics.Tracing.EventSource.dll"
/r:"D:\Microshaoft.Nuget.Packages\Microsoft.Diagnostics.Tracing.TraceEvent.1.0.40\lib\net40\Microsoft.Diagnostics.Tracing.TraceEvent.dll"
*/
namespace Test_OopConsoleTraceEventListenerMonitor_TraceControllerEventsConsumer
{
using Microshaoft;
using Microsoft.Diagnostics.Tracing;
using Microsoft.Diagnostics.Tracing.Session;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
class Program
{
static TextWriter Out = Console.Out;
static void Main(string[] args)
{
Console.Title = Process.GetCurrentProcess().ProcessName;
Action<long, TraceEventDispatcher, TraceEventSession, TraceEvent>
action =
(id, source, session, data) =>
{
var s = data
.PayloadNames
.Select
(
(x) =>
{
return
string
.Format
(
"{1}{0}{2}"
, " : "
, x
, data.PayloadByName(x)
);
}
)
.Aggregate
(
(x, y) =>
{
return
string
.Format
(
"{1}{0}{2}"
, "\r\n"
, x
, y
);
}
);
s = string
.Format
(
"{1}{0}{3}{0}{2}"
, "\r\n"
, ">>>>>>>>>>"
, "<<<<<<<<<<"
, string
.Format
(
"{2}{0}{3}{1}{4}"
, " : "
, "\r\n"
, nameof(data.EventName)
, string
.Format
(
"{0} hits ({1})"
, data.EventName
, id
)
, s
)
);
Console.WriteLine(s);
if (session != null)
{
Console.WriteLine(session.FileName);
}
};
var providerName = "Microshaoft-EventLogEventSource-001";
var sessionName = "zTest";
var tracedFileName = @"D:\EtwLogs\zTest.etl";
var tracingFileName = string.Empty;
//@"D:\EtwLogs\zTest3.etl";
//+ string
// .Format
// (
// "{1}{0}{2}{0}{3}{0}{4}"
// , "."
// , providerName
// , sessionName
// , DateTimeHelper.GetAlignSecondsDateTime(DateTime.Now, 60).ToString("yyyy-MM-dd.HH")
// , "etl"
// );
var traceEvents = new string[]
{
"WriteEvent1Log"
//, "WriteEvent2Log"
};
TraceEventsHelper
.TraceETWTraceEventSourceAsync
(
providerName
, tracedFileName
, traceEvents
, action
, needCountHits : true
);
TraceEventsHelper
.RealTimeTraceEventSessionAsync
(
providerName
, sessionName + "1"
, tracingFileName
, traceEvents
, action
, traceEventSourceType: TraceEventSourceType.Session
, needCountHits: true
);
var tracker = new TraceEventsTracker();
//var tracingFileName = "";
tracker
.RealTimeTraceEventSessionAsync
(
providerName
, sessionName + "2"
, tracingFileName
, traceEvents
,
(
long id
, TraceEventDispatcher source
, TraceEventSession session
, TraceEvent data
) =>
{
action(id, source, session, data);
}
, needCountHits: true
);
//tracker = new TraceEventsTracker();
//tracker
// .TraceETWTraceEventSourceAsync
// (
// providerName
// , etlFileName
// , traceEvents
// , true
// ,
// (
// long id
// , TraceEventDispatcher source
// , TraceEventSession session
// , TraceEvent data
// ) =>
// {
// action(id, source, session, data);
// }
// );
Console.ReadLine();
}
}
}
namespace Microshaoft
{
using Microsoft.Diagnostics.Tracing;
using Microsoft.Diagnostics.Tracing.Session;
//using Diagnostics.Tracing.Parsers;
using System;
using System.IO;
using System.Threading.Tasks;
using System.Threading;
public class TraceEventsTracker
{
public Task<bool> RealTimeTraceEventSessionAsync
(
string providerName
, string sessionName
, string tracingFileName = null
, string[] traceEvents = null
, Action
<
long
, TraceEventDispatcher
, TraceEventSession
, TraceEvent
> onOneEventTracedOnceProcessAction = null
, TraceEventProviderOptions traceEventProviderOptions = null
, TraceEventSessionOptions traceEventSessionOptions = TraceEventSessionOptions.Create
, TraceEventSourceType traceEventSourceType = TraceEventSourceType.MergeAll
, TraceEventLevel traceEventLevel = TraceEventLevel.Always
, ulong matchKeywords = ulong.MaxValue
, bool needCountHits = false
)
{
return
Task
.Factory
.StartNew<bool>
(
() =>
{
return
RealTimeTraceEventSession
(
providerName
, sessionName
, tracingFileName
, traceEvents
, onOneEventTracedOnceProcessAction
, traceEventProviderOptions
, traceEventSessionOptions
, traceEventSourceType
, traceEventLevel
, matchKeywords
, needCountHits
);
}
);
}
public bool RealTimeTraceEventSession
(
string providerName
, string sessionName
, string tracingFileName = null
, string[] traceEvents = null
, Action
<
long
, TraceEventDispatcher
, TraceEventSession
, TraceEvent
> onOneEventTracedOnceProcessAction = null
, TraceEventProviderOptions traceEventProviderOptions = null
, TraceEventSessionOptions traceEventSessionOptions = TraceEventSessionOptions.Create
, TraceEventSourceType traceEventSourceType = TraceEventSourceType.MergeAll
, TraceEventLevel traceEventLevel = TraceEventLevel.Always
, ulong matchKeywords = ulong.MaxValue
, bool needCountHits = false)
{
var r = false;
if
(
traceEvents != null
&&
traceEvents.Length > 0
&&
onOneEventTracedOnceProcessAction != null
)
{
r = TraceEventsHelper
.RealTimeTraceEventSession
(
providerName
, sessionName
, tracingFileName
, traceEvents
, onOneEventTracedOnceProcessAction
, traceEventProviderOptions
, traceEventSessionOptions
, traceEventSourceType
, traceEventLevel
, matchKeywords
, needCountHits
);
}
return r;
}
public Task<bool> TraceETWTraceEventSourceAsync
(
string providerName
, string tracedFileName
, string[] traceEvents = null
, Action
<
long
, TraceEventDispatcher
, TraceEventSession
, TraceEvent
> onOneEventTracedOnceProcessAction = null
, TraceEventProviderOptions traceEventProviderOptions = null
, TraceEventSourceType traceEventSourceType = TraceEventSourceType.MergeAll
, TraceEventLevel traceEventLevel = TraceEventLevel.Always
, ulong matchKeywords = ulong.MaxValue
, bool needCountHits = false
)
{
return
Task
.Factory
.StartNew<bool>
(
() =>
{
return
TraceETWTraceEventSource
(
providerName
, tracedFileName
, traceEvents
, onOneEventTracedOnceProcessAction
, traceEventProviderOptions
, traceEventSourceType
, traceEventLevel
, matchKeywords
, needCountHits
);
}
);
}
public bool TraceETWTraceEventSource
(
string providerName
, string tracedFileName
, string[] traceEvents = null
, Action
<
long
, TraceEventDispatcher
, TraceEventSession
, TraceEvent
> onOneEventTracedOnceProcessAction = null
, TraceEventProviderOptions traceEventProviderOptions = null
, TraceEventSourceType traceEventSourceType = TraceEventSourceType.MergeAll
, TraceEventLevel traceEventLevel = TraceEventLevel.Always
, ulong matchKeywords = ulong.MaxValue
, bool needCountHits = false
)
{
var r = false;
if
(
traceEvents != null
&&
traceEvents.Length > 0
&&
onOneEventTracedOnceProcessAction != null
)
{
r = TraceEventsHelper
.TraceETWTraceEventSource
(
providerName
, tracedFileName
, traceEvents
, onOneEventTracedOnceProcessAction
, traceEventProviderOptions
, traceEventSourceType
, traceEventLevel
, matchKeywords
, needCountHits
);
}
return r;
}
}
public static class TraceEventsHelper
{
private static TextWriter Out = Console.Out;
public static Task<bool> TraceETWTraceEventSourceAsync
(
string providerName
, string tracedFileName
, string[] traceEvents = null
, Action
<
long
, TraceEventDispatcher
, TraceEventSession
, TraceEvent
> onOneEventTracedOnceProcessAction = null
, TraceEventProviderOptions traceEventProviderOptions = null
, TraceEventSourceType traceEventSourceType = TraceEventSourceType.MergeAll
, TraceEventLevel traceEventLevel = TraceEventLevel.Always
, ulong matchKeywords = ulong.MaxValue
, bool needCountHits = false
)
{
return
Task
.Factory
.StartNew<bool>
(
() =>
{
return
TraceETWTraceEventSource
(
providerName
, tracedFileName
, traceEvents
, onOneEventTracedOnceProcessAction
, traceEventProviderOptions
, traceEventSourceType
, traceEventLevel
, matchKeywords
, needCountHits
);
}
,
TaskCreationOptions.LongRunning
|
TaskCreationOptions.DenyChildAttach
);
}
public static bool TraceETWTraceEventSource
(
string providerName
, string tracedFileName
, string[] traceEvents = null
, Action
<
long
, TraceEventDispatcher
, TraceEventSession
, TraceEvent
> onOneEventTracedOnceProcessAction = null
, TraceEventProviderOptions traceEventProviderOptions = null
, TraceEventSourceType traceEventSourceType = TraceEventSourceType.MergeAll
, TraceEventLevel traceEventLevel = TraceEventLevel.Always
, ulong matchKeywords = ulong.MaxValue
, bool needCountHits = false
)
{
var r = false;
if (!(TraceEventSession.IsElevated() ?? false))
{
Out.WriteLine("To turn on ETW events you need to be Administrator, please run from an Admin process.");
return r;
}
if
(
traceEvents != null
&&
traceEvents.Length > 0
&&
onOneEventTracedOnceProcessAction != null
)
{
using (var source = new ETWTraceEventSource(tracedFileName, traceEventSourceType))
{
//闭包
long sequence = 0;
RegisterCallbacks
(
providerName
, traceEvents
, source
, null
, (x, y, z) =>
{
long id = 0;
if (needCountHits)
{
id = Interlocked.Increment(ref sequence);
}
onOneEventTracedOnceProcessAction
(
id
, x
, y
, z
);
}
);
source.Process(); // call the callbacks for each event
}
}
return true;
}
public static Task<bool> RealTimeTraceEventSessionAsync
(
string providerName
, string sessionName
, string tracingFileName = null
, string[] traceEvents = null
, Action
<
long
, TraceEventDispatcher
, TraceEventSession
, TraceEvent
> onOneEventTracedOnceProcessAction = null
, TraceEventProviderOptions traceEventProviderOptions = null
, TraceEventSessionOptions traceEventSessionOptions = TraceEventSessionOptions.Create
, TraceEventSourceType traceEventSourceType = TraceEventSourceType.MergeAll
, TraceEventLevel traceEventLevel = TraceEventLevel.Always
, ulong matchKeywords = ulong.MaxValue
, bool needCountHits = false
)
{
return
Task
.Factory
.StartNew<bool>
(
() =>
{
return
RealTimeTraceEventSession
(
providerName
, sessionName
, tracingFileName
, traceEvents
, onOneEventTracedOnceProcessAction
, traceEventProviderOptions
, traceEventSessionOptions
, traceEventSourceType
, traceEventLevel
, matchKeywords
, needCountHits
);
}
,
TaskCreationOptions.LongRunning
|
TaskCreationOptions.DenyChildAttach
);
}
public static bool RealTimeTraceEventSession
(
string providerName
, string sessionName
, string tracingFileName = null
, string[] traceEvents = null
, Action
<
long
, TraceEventDispatcher
, TraceEventSession
, TraceEvent
> onOneEventTracedOnceProcessAction = null
, TraceEventProviderOptions traceEventProviderOptions = null
, TraceEventSessionOptions traceEventSessionOptions = TraceEventSessionOptions.Create
, TraceEventSourceType traceEventSourceType = TraceEventSourceType.MergeAll
, TraceEventLevel traceEventLevel = TraceEventLevel.Always
, ulong matchKeywords = ulong.MaxValue
, bool needCountHits = false
)
{
var r = false;
if (!(TraceEventSession.IsElevated() ?? false))
{
Out.WriteLine("To turn on ETW events you need to be Administrator, please run from an Admin process.");
return r;
}
var needTracingFile = !string.IsNullOrEmpty(tracingFileName);
if
(
traceEvents != null
&&
traceEvents.Length > 0
&&
onOneEventTracedOnceProcessAction != null
)
{
using
(
var session =
(
needTracingFile
?
new TraceEventSession
(
sessionName
, tracingFileName
, traceEventSessionOptions
)
{
StopOnDispose = true
}
:
new TraceEventSession
(
sessionName
, traceEventSessionOptions
)
{
StopOnDispose = true
}
)
)
{
using
(
var source =
(
needTracingFile
?
new ETWTraceEventSource(tracingFileName)
:
session.Source
)
)
{
long sequence = 0;
RegisterCallbacks
(
providerName
, traceEvents
, source
, session
, (x, y, z) =>
{
long id = 0;
if (needCountHits)
{
id = Interlocked.Increment(ref sequence);
}
onOneEventTracedOnceProcessAction
(
id
, x
, y
, z
);
}
);
var restarted = session
.EnableProvider
(
providerName
, traceEventLevel
, matchKeywords
, traceEventProviderOptions
);
source
.Process();
r = true;
}
}
}
return r;
}
private static void RegisterCallbacks
(
string providerName
, string[] traceEvents
, TraceEventDispatcher source
, TraceEventSession session
, Action
<
TraceEventDispatcher
, TraceEventSession
, TraceEvent
> onOneEventTracedOnceProcessAction
)
{
int l = traceEvents.Length;
for (int i = 0; i < l; i++)
{
var eventName = traceEvents[i];
var action = onOneEventTracedOnceProcessAction;
if (action != null)
{
if (string.Compare(eventName, "*") == 0)
{
source
.Dynamic
.All +=
delegate (TraceEvent data)
{
action(source, session, data);
};
}
else if (string.Compare(eventName, "UnhandledEvents") == 0)
{
source
.UnhandledEvents
+= delegate (TraceEvent data)
{
action(source, session, data);
};
}
else
{
source
.Dynamic
.AddCallbackForProviderEvent
(
providerName
, eventName
, delegate (TraceEvent data)
{
action(source, session, data);
}
);
}
}
}
}
}
}
namespace Microshaoft
{
using System;
using System.IO;
using System.Globalization;
public static class DateTimeHelper
{
public static void GetAlignSecondsDateTimes<T>
(
DateTime time
, params Tuple<long, Func<DateTime, long, DateTime, T, T>>[] processAlignSecondsDateTimesFuncs
)
{
T r = default(T);
foreach (var x in processAlignSecondsDateTimesFuncs)
{
var alignSeconds = x.Item1;
var alignTime = DateTimeHelper.GetAlignSecondsDateTime(time, alignSeconds);
if (x.Item2 != null)
{
r = x.Item2(time, alignSeconds, alignTime, r);
}
}
}
public static bool IsVaildateTimestamp(DateTime timeStamp, int timeoutSeconds)
{
long l = SecondsDiffNow(timeStamp);
return ((l > 0) && (l < timeoutSeconds));
}
public static long MillisecondsDiffNow(DateTime time)
{
long now = DateTime.Now.Ticks;
long t = time.Ticks;
return (t - now) / 10000;
}
public static long SecondsDiffNow(DateTime time)
{
return MillisecondsDiffNow(time) / 1000;
}
public static DateTime GetAlignSecondsDateTime(DateTime time, long alignSeconds)
{
long ticks = time.Ticks;
ticks -= ticks % (10000 * 1000 * alignSeconds);
DateTime dt = new DateTime(ticks);
return dt;
}
public static string GetDateTimeString(DateTime time, string format)
{
return time.ToString(format);
}
public static DateTime GetPeriodBeginDate(DateTime time, int days)
{
DateTime r = GetAlignSecondsDateTime(time, 86400 * days);
return r;
}
public static DateTime GetPeriodEndDate(DateTime time, int days)
{
DateTime r = GetPeriodBeginDate(time, days).AddDays(days - 1);
return r;
}
public static DateTime GetWeekMondayDateTime(DateTime time)
{
DateTime r = GetAlignSecondsDateTime(time, 86400 * 7);
return r;
}
public static DateTime GetWeekTuesdayDateTime(DateTime time)
{
DateTime r = GetAlignSecondsDateTime(time, 86400 * 7).AddDays(1);
return r;
}
public static DateTime GetWeekWednesdayDateTime(DateTime time)
{
DateTime r = GetAlignSecondsDateTime(time, 86400 * 7).AddDays(2);
return r;
}
public static DateTime GetWeekThursdayDateTime(DateTime time)
{
DateTime r = GetAlignSecondsDateTime(time, 86400 * 7).AddDays(3);
return r;
}
public static DateTime GetWeekFridayDateTime(DateTime time)
{
DateTime r = GetAlignSecondsDateTime(time, 86400 * 7).AddDays(4);
return r;
}
public static DateTime GetWeekSaturdayDateTime(DateTime time)
{
DateTime r = GetAlignSecondsDateTime(time, 86400 * 7).AddDays(5);
return r;
}
public static DateTime GetWeekSundayDateTime(DateTime time)
{
DateTime r = GetAlignSecondsDateTime(time, 86400 * 7).AddDays(6);
return r;
}
public static DateTime? ParseExactNullableDateTime(string text, string format)
{
DateTime time;
DateTime? r = DateTime.TryParseExact
(
text
, format
, DateTimeFormatInfo.InvariantInfo
, DateTimeStyles.None
, out time
) ? time as DateTime? : null;
return r;
}
}
}