在TraceProcessor中公开启动时间

问题描述 投票:0回答:1

我看到Microsoft.Windows.EventTracing.Interop.Metadata.NativeTraceLogfileHeader包含BootTime的值。在某些情况下这可能很有用。通过ITraceMetaData接口暴露的任何机会还是可以通过其他方式访问?

// Microsoft.Windows.EventTracing.Metadata.ITraceMetadata
using Microsoft.Windows.EventTracing;

public interface ITraceMetadata
{
    Version OSVersion
    bool Is32Bit
    FrequencyValue ProcessorSpeed
    TraceClockType ClockType
    FrequencyValue PerformanceCounterFrequency
    TraceTimestampValue? ReferenceTimestampValue
    FrequencyValue ProcessorUsageTimerFrequency
    TraceTimestamp FirstAnalyzerDisplayedEventTime
    TraceTimestamp LastEventTime
    TraceDuration AnalyzerDisplayedDuration    
    long LostBufferCount
    long LostEventCount
    string TracePath
    DateTimeOffset StartTime    
    DateTimeOffset StopTime    
    int ProcessorCount    
    int KernelEventVersion
}
c# etw .net-traceprocessing
1个回答
1
投票

我将让当前的团队成员回答有关可以进行哪些更改。从概念上讲,在发布v1 API之前,我认为将这些数据添加到ITraceMetadata是合理的。

我不记得要将此数据添加到API中的其他任何内容。 (我检查了ISystemMetadata,在那儿没看到它。)我知道的唯一解决方法是使用IEventConsumer / IFilteredEventConsumer解析包含该数据的事件的有效负载(总是跟踪中的第一个事件,我认为,无论该事件具有什么ProviderId / Id,我都不会立即记住)。

如果我没记错的话,有效载荷就是TRACE_LOGFILE_HEADER structure。但是请注意,由于该事件中包含LoggerName / LogFileName指针,因此该事件同时具有32位和64位版本(基于跟踪的位数,而不是处理跟踪的计算机的位数)。

编辑:

这里是一个示例exe文件,它通过跟踪标头事件获取启动时间。 (我正在使用trace.Use(),但IFilteredEventConsumer等效。)

using Microsoft.Windows.EventTracing;
using System;
using System.Runtime.InteropServices;

class Program
{
    static int Main(string[] args)
    {
        if (args.Length != 1)
        {
            Console.Error.WriteLine("Usage: GetTraceBootTime.exe <trace.etl>");
            return 1;
        }

        string tracePath = args[0];

        using (ITraceProcessor trace = TraceProcessor.Create(tracePath))
        {
            DateTime? bootTime = null;

            Guid eventTraceProviderId = new Guid("68fdd900-4a3e-11d1-84f4-0000f80464e3");
            trace.Use(new[] { eventTraceProviderId }, e =>
            {
                if (e.Event.Id != 0 || e.Event.Version != 2)
                {
                    return;
                }

                var data = e.Event.Data;
                long rawBootTime;

                if (e.Event.Is32Bit)
                {
                    if (data.Length < Marshal.SizeOf<NativeTraceHeaderEvent32>())
                    {
                        throw new InvalidOperationException("Invalid 32-bit trace header event.");
                    }

                    IntPtr pointer = Marshal.AllocHGlobal(data.Length);
                    Marshal.Copy(data.ToArray(), 0, pointer, data.Length);
                    NativeTraceHeaderEvent32 typedData = Marshal.PtrToStructure<NativeTraceHeaderEvent32>(pointer);
                    Marshal.FreeHGlobal(pointer);
                    rawBootTime = typedData.BootTime;
                }
                else
                {
                    if (data.Length < Marshal.SizeOf<NativeTraceHeaderEvent64>())
                    {
                        throw new InvalidOperationException("Invalid 64-bit trace header event.");
                    }

                    IntPtr pointer = Marshal.AllocHGlobal(data.Length);
                    Marshal.Copy(data.ToArray(), 0, pointer, data.Length);
                    NativeTraceHeaderEvent64 typedData = Marshal.PtrToStructure<NativeTraceHeaderEvent64>(pointer);
                    Marshal.FreeHGlobal(pointer);
                    rawBootTime = typedData.BootTime;
                }

                // See https://docs.microsoft.com/en-us/windows/win32/api/evntrace/ns-evntrace-trace_logfile_header:
                // BootTime is ticks since midnight, January 1, 1601 and is apparently UTC (despite documentation to the
                // contrary).
                DateTime epoch = new DateTime(1601, 1, 1, 0, 0, 0, DateTimeKind.Utc);
                bootTime = epoch.AddTicks(rawBootTime);

                e.Cancel();
            });

            trace.Process();

            Console.WriteLine(bootTime);
        }

        return 0;
    }

    // https://docs.microsoft.com/en-us/windows/win32/api/evntrace/ns-evntrace-trace_logfile_header
    [StructLayout(LayoutKind.Sequential)]
    struct NativeTraceHeaderEvent64
    {
        public uint BufferSize;
        public byte MajorVersion;
        public byte MinorVersion;
        public byte SubVersion;
        public byte SubMinorVersion;
        public uint ProviderVersion;
        public uint NumberOfProcessors;
        public long EndTime;
        public uint TimerResolution;
        public uint MaximumFileSize;
        public uint LogFileMode;
        public uint BuffersWritten;
        public uint StartBuffers;
        public uint PointerSize;
        public uint EventsLost;
        public uint CpuSpeedInMHz;
        public ulong LoggerName;
        public ulong LogFileName;
        public NativeTimeZoneInformation TimeZone;
        public long BootTime;
        public long PerfFreq;
        public long StartTime;
        public uint ReservedFlags;
        public uint BuffersLost;
    }

    // https://docs.microsoft.com/en-us/windows/win32/api/evntrace/ns-evntrace-trace_logfile_header
    [StructLayout(LayoutKind.Sequential)]
    struct NativeTraceHeaderEvent32
    {
        public uint BufferSize;
        public byte MajorVersion;
        public byte MinorVersion;
        public byte SubVersion;
        public byte SubMinorVersion;
        public uint ProviderVersion;
        public uint NumberOfProcessors;
        public long EndTime;
        public uint TimerResolution;
        public uint MaximumFileSize;
        public uint LogFileMode;
        public uint BuffersWritten;
        public uint StartBuffers;
        public uint PointerSize;
        public uint EventsLost;
        public uint CpuSpeedInMHz;
        public uint LoggerName;
        public uint LogFileName;
        public NativeTimeZoneInformation TimeZone;
        public long BootTime;
        public long PerfFreq;
        public long StartTime;
        public uint ReservedFlags;
        public uint BuffersLost;
    }

    // https://docs.microsoft.com/en-us/windows/win32/api/timezoneapi/ns-timezoneapi-time_zone_information
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    struct NativeTimeZoneInformation
    {
        public int Bias;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
        public char[] StandardName;

        public NativeSystemTime StandardDate;

        public int StandardBias;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
        public char[] DaylightName;

        public NativeSystemTime DaylightDate;

        public int DaylightBias;
    }

    // https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-systemtime
    [StructLayout(LayoutKind.Sequential)]
    struct NativeSystemTime
    {
        public short wYear;
        public short wMonth;
        public short wDayOfWeek;
        public short wDay;
        public short wHour;
        public short wMinute;
        public short wSecond;
        public short wMilliseconds;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.