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

标签 .net f# etw perfview

我很困惑如何为现有系统 ETW 提供程序创建 EventListenerEnableEvents 方法需要在 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

Output

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

2015-12-02 更新

我能够使用 SemanticLogging 获取 EventSource 事件记录。 details are here .它正在使用 Microsoft.Diagnostics.Tracing.TraceEvent .使用它似乎是解决方案。

最佳答案

我不太明白我在问什么。我想记录来自 ETL 的事件。在 Vance Morrison 的博客上,he explains EventSource 保持对这些数据项名称和类型的跟踪,以便处理器(EventListeners 或 ETW)。我尝试使用的 EventListener 用于同一进程中的事件。 TraceEvent 可用于从另一个进程获取事件。 samples他提供的非常棒,我用它们来创建这个。

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

关于.net - 现有 ETW 提供程序的 System.Diagnostic.Tracing.EventListener,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34037945/

相关文章:

f# - 将选项类型列表压缩为仅非无元素的最佳方法?

f# - 为什么算术运算符的参数类型默认为 int?

MS SQL Server 跟踪日志的收集

c# - 关于从 Parallel.ForEach() 中调用外部方法是否有任何特殊规则或注意事项?

c# - 如何获取另一个 EXE 的程序集版本(不是文件版本)?

C# WPF 使工具栏在工具栏托盘内右对齐

c# - 在图像控件中显示位图

hash - 如何缓存 AST 的哈希码?

windows - 使用 xperf 列出每个进程访问的文件?

c++ - 为什么 ETW EventWriteString 有二进制负载