Etw EventSourceProvider_EventsProducer.cs OopConsoleTraceEventListenerMonitor_TraceControllerEventsConsumer.cs


// EventSourceProvider_EventsProducer.cs
/*
/r:"D:Microshaoft.Nuget.PackagesMicrosoft.Diagnostics.Tracing.EventSource.Redist.1.1.28lib
et46Microsoft.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#EtwOkEventSourcesinDebug"
                                , 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.PackagesNewtonsoft.Json.7.0.1lib
et45Newtonsoft.Json.dll"
    /r:"D:Microshaoft.Nuget.PackagesMicrosoft.Diagnostics.Tracing.EventSource.Redist.1.1.28lib
et46Microsoft.Diagnostics.Tracing.EventSource.dll"
    /r:"D:Microshaoft.Nuget.PackagesMicrosoft.Diagnostics.Tracing.TraceEvent.1.0.40lib
et40Microsoft.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}"
                                                                        , "
"
                                                                        , x
                                                                        , y
                                                                    );
                                                    }
                                                );
                                s = string
                                        .Format
                                            (
                                                "{1}{0}{3}{0}{2}"
                                                , "
"
                                                , ">>>>>>>>>>"
                                                , "<<<<<<<<<<"
                                                , string
                                                    .Format
                                                        (
                                                            "{2}{0}{3}{1}{4}"
                                                            , " : "
                                                            , "
"
                                                            , 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:EtwLogszTest.etl";
            var tracingFileName = string.Empty;
                                    //@"D:EtwLogszTest3.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;
        }
    }
}

原文地址:https://www.cnblogs.com/Microshaoft/p/5065361.html