现有ETW提供程序的System.Diagnostic.Tracing.EventListener

3

我对如何为现有系统的ETW提供程序创建一个EventListener感到困惑。 EnableEvents方法期望传入一个EventSource实例。我需要手动创建吗?是否有一种方法可以生成该EventSource类?

我可以通过以下任一方式找到提供程序的详细信息:

logman query providers Microsoft-Windows-WinHttp
wevtutil get-publisher Microsoft-Windows-WinHttp

我甚至可以使用以下代码生成 instrumentationManifest xml 文件:

.\PerfView.exe /nogui userCommand DumpRegisteredManifest Microsoft-Windows-WinHttp

open System.Diagnostics.Tracing

let printfn format = Printf.ksprintf System.Diagnostics.Debug.WriteLine format

[<EventSource(Name="Microsoft-Windows-NDIS-PacketCapture", Guid="2ed6006e-4729-4609-b423-3ee7bcd678ef")>]
type NdisPacketCaptureEventSource() =
    inherit EventSource()

let Ethernet = LanguagePrimitives.EnumOfValue<int64, EventKeywords>(0x1L)
let WirelessWAN = LanguagePrimitives.EnumOfValue<int64, EventKeywords>(0x200L)

let Api = LanguagePrimitives.EnumOfValue<int64, EventKeywords>(0x1L)
let Send = LanguagePrimitives.EnumOfValue<int64, EventKeywords>(0x100000000L)

[<EventSource(Name="Microsoft-Windows-WinHttp", Guid="7d44233d-3055-4b9c-ba64-0d47ca40a232")>]
type WinHttpEventSource() =
    inherit EventSource()

type MyEventListener() =
    inherit EventListener()

    override x.OnEventSourceCreated source =
        printfn "OnEventSourceCreated %A" source
        base.OnEventSourceCreated source

    override x.OnEventWritten args =
        printfn "OnEventWritten %A" args
        base.OnEventWritten args

[<EntryPoint>]
let main argv = 
    use listener = new MyEventListener()

//    use ndis = new NdisPacketCaptureEventSource()
//    printfn "Name: %s, Guid: %A" ndis.Name ndis.Guid
//    listener.EnableEvents(ndis, EventLevel.Verbose, EventKeywords.All)
//    listener.EnableEvents(ndis, EventLevel.Verbose, Ethernet)
//    listener.EnableEvents(ndis, EventLevel.Verbose, WirelessWAN)

    use winHttp = new WinHttpEventSource()
//    listener.EnableEvents(winHttp, EventLevel.Verbose, EventKeywords.All)
    listener.EnableEvents(winHttp, EventLevel.Verbose, Send)

//    for i in 0 .. 5 do
//    System.Console.ReadKey() |> ignore
    while true do
        System.Threading.Thread.Sleep 100
    0

输出

我一直无法触发OnEventWritten,不知道原因。有什么想法吗?

2015年12月2日更新

我已经能够使用SemanticLogging记录EventSource事件。 这里有详细信息。它使用Microsoft.Diagnostics.Tracing.TraceEvent,似乎是可能的解决方案。

1个回答

3

我并不太明白自己在问什么。我想记录ETL中的事件。在Vance Morrison的博客文章中,他解释说 EventSource跟踪这些数据项的名称和类型,以便处理器(无论是EventListeners还是ETW)。我尝试使用的EventListener是用于同一进程中的事件。可以使用TraceEvent来获取另一个进程中的事件。他提供的示例很棒,我用它们创建了这个。

open System

// https://www.nuget.org/packages/Microsoft.Diagnostics.Tracing.TraceEvent/
open Microsoft.Diagnostics.Tracing
open Microsoft.Diagnostics.Tracing.Session

// toggle this on for VS Output window or off for Console window
let printfn format = Printf.ksprintf System.Diagnostics.Debug.WriteLine format

[<EntryPoint>]
let main argv = 
    
    if not (TraceEventSession.IsElevated().GetValueOrDefault()) then
        printfn "you must run as admin"
        1

    else 
        let name = "Microsoft-AdoNet-SystemData"
        let guid = TraceEventProviders.GetProviderGuidByName name
        printfn "name: %s, guid: %A" name guid
        use sn = new TraceEventSession("MySession")
        sn.Source.add_AllEvents (fun evt -> printfn "event: %A" evt)
        sn.EnableProvider(name, TraceEventLevel.Verbose) |> ignore
        Console.CancelKeyPress.Add (fun args -> args.Cancel <- true; sn.Dispose())
        sn.Source.Process() |> ignore
        0

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接