Trace に出力した内容を Application Insights に保存する

はじめに

セルフホストしてる WCF サービスで、例外が発生したら Application Insights に記録したい。ただ、WCF 用のパッケージはラボの段階で、しかもリポジトリアーカイブされている。開発されていない。

github.com

今から TelemetryClient を使って Application Insights に送信するコードを書いて回るほどの日程は無い。というか死にゆく WCF のためにそこまでリソースを使いたくない。

そういえばトレースを出力するコードは、いくらか仕込んでいたな。トレースを Application Insights に送信するパッケージはちゃんとある。

www.nuget.org

こいつを使えば良さそうだ。

サービスコントラクトを定義

using System.ServiceModel;

namespace WcfAppInsights.Shared
{
    [ServiceContract]
    public interface IEchoService
    {
        [OperationContract]
        string Echo(string message);
    }
}

WCF サービスを実装

NuGet で Microsoft.ApplicationInsights.TraceListener をインストールし、サービスクラスを実装する。引数で渡された文字列をエラーとしてトレースに出力するだけ。Application Insights にちゃんと送信されるよう、即フラッシュしておく。

using System;
using System.Diagnostics;
using System.ServiceModel;
using WcfAppInsights.Shared;

namespace WcfAppInsights.Server
{
    class Program
    {
        static void Main(string[] args)
        {
            var host = new ServiceHost(typeof(EchoService));
            host.AddServiceEndpoint(
                typeof(IEchoService),
                new NetTcpBinding(),
                "net.tcp://localhost:8081/EchoService");
            host.Open();
            Console.WriteLine("Enter で終了");
            Console.ReadLine();
            host.Close();
        }
    }

    public class EchoService : IEchoService
    {
        public string Echo(string message)
        {
            Trace.TraceError(message);
            Trace.Flush();

            return message;
        }
    }
}

App.config を記述

トレースを Application Insights に送信するために、Microsoft.ApplicationInsights.TraceListener.ApplicationInsightsTraceListener を使うように構成する。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.diagnostics>
    <trace>
      <listeners>
        <add name="myAppInsightsListener" type="Microsoft.ApplicationInsights.TraceListener.ApplicationInsightsTraceListener, Microsoft.ApplicationInsights.TraceListener" />
      </listeners>
    </trace>
  </system.diagnostics>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
  </startup>
</configuration>

ApplicationInsights.config を追加

ApplicationInsightsTraceListener というか TelemetryClient は、コードで InstrumentationKey を指定しなかったら、ApplicationInsights.config に記述してあるものを使うようだ。

<?xml version="1.0" encoding="utf-8"?>
<ApplicationInsights xmlns="http://schemas.microsoft.com/ApplicationInsights/2013/Settings">
  <InstrumentationKey>your-instrumentation-key</InstrumentationKey>
</ApplicationInsights>

ビルド時にちゃんと出力先にコピーされるようにしておく。うっかり忘れて気づくまで時間かかった。

WCF クライアントを実装

using System;
using System.ServiceModel;
using WcfAppInsights.Shared;

namespace WcfAppInsights.Client
{
    class Program
    {
        static void Main(string[] args)
        {
            var channel = ChannelFactory<IEchoService>.CreateChannel(
                new NetTcpBinding(),
                new EndpointAddress("net.tcp://localhost:8081/EchoService"));

            var reply = channel.Echo("Hello Application Insights");

            Console.WriteLine(reply);

            Console.WriteLine("Enter で終了");
            Console.ReadLine();
            ((IClientChannel)channel).Close();
        }
    }
}

実行結果

WCF サーバーと WCF クライアントを実行して、少し待つと、トレースに出力したメッセージが Application Insights に送信されていることを確認できた。

f:id:griefworker:20210510151249p:plain

おわりに

Application Insights の使い方を詳しく解説してくれる書籍が欲しい。技術同人誌でもいい。