Source/Tx.Bond/BinaryEtwObservable.cs (126 lines of code) (raw):

// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. namespace Tx.Bond { using System; using System.Reactive; using System.Reactive.Linq; using Tx.Windows; /// <summary> /// Uses Tx.Windows implementation of Etw log parser and converts the objects into BinaryEnvelope objects. Use a BinaryConfigTypeMap derived implementation /// along with this class to convert into required datatypes. /// </summary> public static class BinaryEtwObservable { /// <summary> /// Takes an array of files and creates an observer that retrieves all BinaryEnvelope type events. These Events have EventId 0 /// and belong to EtwBinaryEventManifestProviderId /// </summary> /// <param name="files">Up to 63 files to read.</param> /// <returns>Sequence of events ordered by timestamp.</returns> public static IObservable<IEnvelope> FromFiles(params string[] files) { return FromFiles(BinaryEventSource.Log.Guid, false, null, null, files); } /// <summary> /// Takes an array of files and creates an observer that retrieves all BinaryEnvelope type events. These Events have EventId 0 /// and belong to EtwBinaryEventManifestProviderId /// </summary> /// <param name="startTime">Start time of sequence of events, if null then DateTime.MinValue will be used.</param> /// <param name="endTime">End time of sequence of events, if null then DateTime.MaxValue will be used.</param> /// <param name="files">Up to 63 files to read.</param> /// <returns>Sequence of events ordered by timestamp.</returns> public static IObservable<IEnvelope> FromFiles(DateTime startTime, DateTime endTime, params string[] files) { return FromFiles(BinaryEventSource.Log.Guid, false, startTime, endTime, files); } public static IObservable<IEnvelope> FromSequentialFiles(params string[] files) { return FromFiles(BinaryEventSource.Log.Guid, true, null, null, files); } public static IObservable<IEnvelope> FromSequentialFiles(DateTime startTime, DateTime endTime, params string[] files) { return FromFiles(BinaryEventSource.Log.Guid, true, startTime, endTime, files); } public static IObservable<EventManifest> BinaryMainfestFromFiles(params string[] files) { return BinaryManifestFromFiles(BinaryEventSource.Log.Guid, false, null, null, files); } public static IObservable<EventManifest> BinaryMainfestFromFiles(DateTime startTime, DateTime endTime, params string[] files) { return BinaryManifestFromFiles(BinaryEventSource.Log.Guid, false, startTime, endTime, files); } public static IObservable<EventManifest> BinaryManifestFromSequentialFiles(params string[] files) { return BinaryManifestFromFiles(BinaryEventSource.Log.Guid, true, null, null, files); } public static IObservable<EventManifest> BinaryManifestFromSequentialFiles(DateTime startTime, DateTime endTime, params string[] files) { return BinaryManifestFromFiles(BinaryEventSource.Log.Guid, true, startTime, endTime, files); } /// <summary> /// Takes an array of files and creates an observer that retrieves all BinaryEnvelope type events. These Events have EventId 0, 1 and 2. /// and belong to specified provider. /// </summary> /// <param name="providerId">Identifier of ETW provider.</param> /// <param name="useSequentialReader">Flag to specify if the input ETL files are already ordered by timestamp.</param> /// <param name="startTime">Start time of sequence of events, if null then DateTime.MinValue will be used.</param> /// <param name="endTime">End time of sequence of events, if null then DateTime.MaxValue will be used.</param> /// <param name="files">Either unlimited number of ETL files containing events ordered by timestamp or up to 63 files to read.</param> /// <returns>Sequence of events ordered by timestamp.</returns> public static IObservable<IEnvelope> FromFiles( Guid providerId, bool useSequentialReader, DateTime? startTime, DateTime? endTime, params string[] files) { var parser = new BinaryEtwParser(providerId); var etwObservable = CreateEtwObservable(useSequentialReader, startTime, endTime, files); return etwObservable .Select(parser.Parse) .Where(item => item != null); } /// <summary> /// Creates a listener to ETW real-time session for BinaryEnvelope events. These Events have EventId 0, 1 and 2. /// and belong to specified provider. /// </summary> /// <param name="providerId">Identifier of ETW provider.</param> /// <param name="sessionName">Session name.</param> /// <returns>Sequence of events ordered by timestamp.</returns> public static IObservable<IEnvelope> FromSession( Guid providerId, string sessionName) { var parser = new BinaryEtwParser(providerId); var etwObservable = EtwObservable.FromSession(sessionName); return etwObservable .Select(parser.Parse) .Where(item => item != null); } public static IObservable<EventManifest> BinaryManifestFromFiles( Guid providerId, bool useSequentialReader, DateTime? startTime, DateTime? endTime, params string[] files) { var parser = new BinaryEtwParser(providerId); var etwObservable = CreateEtwObservable(useSequentialReader, startTime, endTime, files); return etwObservable .Select(parser.ParseManifest) .Where(item => item != null); } private static IObservable<EtwNativeEvent> CreateEtwObservable( bool useSequentialReader, DateTime? startTime, DateTime? endTime, params string[] files) { if (startTime.HasValue != endTime.HasValue) { throw new ArgumentException("Specify both start and end times or leave both of them null."); } if (startTime.HasValue && startTime.Value >= endTime.Value) { throw new ArgumentException("Start time should be less than end time."); } if (files == null) { throw new ArgumentNullException(nameof(files)); } if (files.Length == 0) { throw new ArgumentException("The Files parameter should contain at least one element."); } IObservable<EtwNativeEvent> etwObservable; if (useSequentialReader) { if (startTime.HasValue) { etwObservable = EtwObservable.FromSequentialFiles(startTime.Value, endTime.Value, files); } else { etwObservable = EtwObservable.FromSequentialFiles(files); } } else { if (startTime.HasValue) { etwObservable = EtwObservable.FromFiles(startTime.Value, endTime.Value, files); } else { etwObservable = EtwObservable.FromFiles(files); } } return etwObservable; } } }