예제 #1
0
        /// <summary>
        /// Creates a new instance of the <see cref="RawListener"/> class to listen to an
        /// ETW real-time session.
        /// </summary>
        /// <param name="sessionName">
        /// Name of the ETW real-time session from which the client wants to listen for events.
        /// </param>
        /// <param name="eventRecordCallback">
        /// The event record callback provided by the client. This can be null if the
        /// eventBufferCallback parameter is not.
        /// </param>
        /// <param name="eventBufferCallback">
        /// The event buffer callback provided by the client. This can be null if the
        /// eventRecordCallback parameter is not.
        /// </param>
        /// <param name="useRawTimestamps">
        /// True to indicate that the timestamps of events will be raw or false if ETW should convert them to FILETIME.
        /// </param>
        /// <returns>
        /// The new instance of the <see cref="RawListener"/> class to listen to an
        /// ETW real-time session.
        /// </returns>
        public static RawListener CreateRealTimeListener(
            string sessionName,
            NativeMethods.EventRecordCallback eventRecordCallback,
            NativeMethods.EventTraceBufferCallback eventBufferCallback,
            bool useRawTimestamps = true)
        {
            if (string.IsNullOrEmpty(sessionName))
            {
                throw new ArgumentException("Session name cannot be null or empty", "sessionName");
            }

            return(new RawListener(new[] { sessionName }, eventRecordCallback, eventBufferCallback, false, useRawTimestamps));
        }
예제 #2
0
        /// <summary>
        /// Creates a new instance of the <see cref="RawListener"/> class to process a set of ETL files.
        /// </summary>
        /// <param name="etlFiles">
        /// Sequence with the names of the ETL files from which the client wants to listen for events.
        /// </param>
        /// <param name="eventRecordCallback">
        /// The event record callback provided by the client. This can be null if the
        /// eventBufferCallback parameter is not.
        /// </param>
        /// <param name="eventBufferCallback">
        /// The event buffer callback provided by the client. This can be null if the
        /// eventRecordCallback parameter is not.
        /// </param>
        /// <param name="useRawTimestamps">
        /// True to indicate that the timestamps of events will be raw or false if ETW should convert them to FILETIME.
        /// </param>
        /// <returns>
        /// The new instance of the <see cref="RawListener"/> class to process a set of ETL files.
        /// </returns>
        public static RawListener CreateEtlFileListener(
            IEnumerable <string> etlFiles,
            NativeMethods.EventRecordCallback eventRecordCallback,
            NativeMethods.EventTraceBufferCallback eventBufferCallback,
            bool useRawTimestamps = true)
        {
            if (etlFiles == null)
            {
                throw new ArgumentNullException("etlFiles");
            }

            var nonEmptyEtlsEnum = from etl in etlFiles
                                   where !string.IsNullOrEmpty(etl)
                                   select etl;
            var nonEmptyEtls = nonEmptyEtlsEnum.ToList();

            if (nonEmptyEtls.Count < 1)
            {
                throw new ArgumentException(
                          "At least one non-null and non-empty etl file name must be provided");
            }

            return(new RawListener(nonEmptyEtls, eventRecordCallback, eventBufferCallback, true, useRawTimestamps));
        }
예제 #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="RawListener"/> class.
        /// </summary>
        /// <param name="sessionOrEtlFiles">
        /// An enumerable with a single item if listen to an ETW real-time session or a sequence of ETL file names
        /// that are going to be processed together.
        /// </param>
        /// <param name="eventRecordCallback">
        /// The event record callback provided by the client. This can be null if the
        /// eventBufferCallback parameter is not.
        /// </param>
        /// <param name="eventBufferCallback">
        /// The event buffer callback provided by the client. This can be null if the
        /// eventRecordCallback parameter is not.
        /// </param>
        /// <param name="isFileTrace">
        /// Boolean to indicate whether this is a file or real-time ETW listener.
        /// </param>
        /// <param name="useRawTimestamps">
        /// True to indicate that the timestamps of events will be raw or false if ETW should convert them to FILETIME.
        /// </param>
        private RawListener(
            IEnumerable <string> sessionOrEtlFiles,
            NativeMethods.EventRecordCallback eventRecordCallback,
            NativeMethods.EventTraceBufferCallback eventBufferCallback,
            bool isFileTrace,
            bool useRawTimestamps = true)
        {
            if (sessionOrEtlFiles == null)
            {
                throw new ArgumentNullException("sessionOrEtlFiles");
            }

            var tracesEnum = from trace in sessionOrEtlFiles
                             where !string.IsNullOrEmpty(trace)
                             select trace;
            var traces = tracesEnum.ToList();

            if (traces.Count < 1)
            {
                throw new ArgumentException(
                          "At least one non-null, non-empty session or etl file name must be provided");
            }

            if (eventRecordCallback == null && eventBufferCallback == null)
            {
                throw new ArgumentException("At least one of the callbacks must be specified");
            }

            var traceIndex = 0;

            this.traceHandles = new ulong[traces.Count];
            this.traceLogs    = new NativeMethods.EventTraceLogfilew[traces.Count];
            foreach (var traceName in traces)
            {
                this.traceLogs[traceIndex].EventCallback  = eventRecordCallback;
                this.traceLogs[traceIndex].BufferCallback = eventBufferCallback;
                this.traceLogs[traceIndex].LogFileMode    = NativeMethods.ProcessTraceModeEventRecord
                                                            | (useRawTimestamps ? NativeMethods.ProcessTraceModeRawTimestamp : 0);

                if (isFileTrace)
                {
                    this.traceLogs[traceIndex].LogFileName = traceName;
                }
                else
                {
                    this.traceLogs[traceIndex].LoggerName   = traceName;
                    this.traceLogs[traceIndex].LogFileMode |= NativeMethods.ProcessTraceModeRealTime;
                }

                // New ETW session mode for Windows 8.1, Server 2012 R2, and later that avoids
                // slow consumers on one session to affect other sessions. Adding by default to all
                // sessions since it does not have adverse impact and it is just ignored by legacy OSes.
                this.traceLogs[traceIndex].LogFileMode |= NativeMethods.EventTraceIndependentSessionMode;

                var traceHandle = NativeMethods.OpenTrace(ref this.traceLogs[traceIndex]);
                if ((!Is64BitProcess && traceHandle == NativeMethods.InvalidTracehandle32) ||
                    (Is64BitProcess && traceHandle == NativeMethods.InvalidTracehandle64))
                {
                    throw new Win32Exception(string.Format(
                                                 CultureInfo.InvariantCulture,
                                                 "OpenTrace call for trace '{0}' failed.",
                                                 traceName));
                }

                this.traceHandles[traceIndex++] = traceHandle;
            }
        }