2018年8月14日火曜日

C# ETW(Event Tracing for Windows)からログを取得する

ETW (Event Tracing for Windows) は Windows OS のイベントトレースの仕組みです。ETW を使用するとログの出力とログの記録を分離することができ、アプリケーションのパフォーマンス向上などのメリットがあります。ETW からログを取得してみます。



EtwStream + LINQPad を使う


LINQPad を利用しているのであれば、EtwStream.LinqPad 拡張を使うと簡単にログを取得できます。LINQpad の NuGet インストール機能は Developer エディション以上が必要ですが、手作業で参照アセンブリを登録するのであれば Free エディションでも動作させることはできます。

LINQPad
LINQPad でログを表示

追加した参照アセンブリ

(メニューの Query ⇒ References and Properties から追加)
EtwStream.Core.dll
EtwStream.LinqPad.dll
Microsoft.Diagnostics.Tracing.TraceEvent.dll
System.Reactive.Core.dll
System.Reactive.Interfaces.dll
System.Reactive.Linq.dll

追加した名前空間

(メニューの Query ⇒ Namespace imports から追加)
EtwStream

発行したクエリ

ObservableEventListener.FromTraceEvent("プロバイダ名またはID")
.DumpWithColor();



C#でビューアーを自作してみた


EtwStream.Core を利用した簡単なビューアーを作成してみました。.NET Framework 4.6 フォームアプリケーションです。

GitHub mxProject/EtwLogViewer
https://github.com/mxProject/EtwLogViewer

自作ビューアー
自作ビューアーでログを表示


表示対象プロバイダのリストや表示対象項目は XML 形式の設定ファイルで指定します。
表示対象に指定できる項目は、TraceEvent クラスの各プロパティと任意のペイロードです。

  • TraceEvent クラスの public プロパティ。
  • ペイロード名。ペイロードの項目名はプロバイダによって異なりますので、表示したい項目名を直接指定する方法としました。Field の Name の先頭文字がドットである場合はペイロードであるとみなします。
そのほか、次の項目も指定できます。
  • Payloads:ペイロードの名前と値を連結した文字列。書式は name1=value1; name2=value2; … です。
  • ProviderFriendlyName:設定ファイルのプロバイダ情報で設定した FriendlyName の値。

<?xml version="1.0" encoding="shift_jis"?>
<EtwLogViewerConfig
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">

  <!-- ETW Providers -->
  <Providers>
    <Provider FriendlyName="mxLogger"
      Name="mxProject.Logging.Loggers.ETWLogger"
      ID="{FAE1403F-2B75-493D-96C4-12B330928A97}" />
    <Provider FriendlyName="NLog"
      Name="LowLevelDesign-NLogEtwSource" />
    <Provider FriendlyName=".NET CLR"
      ID="{E13C0D23-CCBC-4E12-931B-D9CC2EEE27E4}" />
  </Providers>
  
  <!-- Known payloads -->
  <KnownPayloads>
    <string>LoggerName</string>
    <string>Sequence</string>
    <string>Time</string>
    <string>Message</string>
    <string>MemberName</string>
    <string>FilePath</string>
    <string>Line</string>
  </KnownPayloads>

  <!-- Visible fields -->
  <!--
    To specify the payload, add a dot before the item name.
    ex) .Message
  -->
  <Fields>
    <Field Name="TimeStamp" Width="120" />
    <Field Name="ProviderFriendlyName" Width="120" />
    <Field Name="ProviderName" Width="120" />
    <Field Name="FormattedMessage" Width="200" />
    <Field Name=".LoggerName" Width="100" />
    <Field Name=".Message" Width="200" />
    <Field Name=".Sequence" Width="70" />
    <Field Name=".Time" Width="120" />
    <Field Name=".MemberName" Width="100" />
    <Field Name=".FilePath" Width="100" />
    <Field Name=".Line" Width="50" />
    <Field Name="Payloads" Width="300" />
  </Fields>

</EtwLogViewerConfig>


Windows に登録されているプロバイダ


非常に多くのプロバイダが登録されています。それらの Guid を指定すれば、出力されているログの内容を確認することができます。

tech.guitarrapc.com - Event Tracing for Windows (ETW) の トレースプロバイダーリストを取得してみる
http://tech.guitarrapc.com/entry/2016/01/07/100248

0 件のコメント:

コメントを投稿

paiza のスキルチェックをやってみました

いまさら感はありますが、 paiza のスキルチェックをやってみました。指定された時間内にコードを書いてユニットテストにかけ、その結果を基に評価を数値化してくれるというものですが、ゲーム感覚で空き時間を見つけて進めていこうと考えています。 どうやら時間が短いほど高い評価を得...