New Relic の APM Agentはアプリケーション/WebサーバーのようなWebアプリだけでなく、バッチ処理やGUIアプリケーションのようなアプリも計測できます。その中でも、.NET Agentを使うと.NET Frameworkおよび.NET Coreで開発されたWindowsサービスアプリケーションも計測できます。ただ、必要な設定がいくつかあるため、本記事にてまとめてご紹介しようと思います。

必要となる設定はAgentの有効化、およびcustom instrumentationの大きく2つです。Agentの有効化は.NET Frameworkと.NET Coreで異なります。custom instrumentationの適用は両者で同じです。

Agentの有効化 (.NET Frameworkの場合)

.NET Frameworkの場合の手順はドキュメントの「IISにないアプリのエージェントの有効化」に記載があります。設定方法は大きく3つあり、アプリの設定ファイル(exeファイルであれば、<ファイル名>.exe.config)、グローバルもしくはローカルのnewrelic.configファイルのapplication name属性、ローカルのnewrelic.configファイルのconfiguration agentEnabled属性、の3つです。

設定ファイルおよびローカルのnewrelic.configファイルの場合、サービスとして起動されるexeファイルに対応する設定ファイルもしくは同じフォルダにあるnewrelic.configファイルに記述します。

application name属性に指定する場合、nameに指定する値はプロセス名です。殆どの場合、実行ファイルの拡張子つきファイル名となるはずです。application name属性で有効化するときの注意点として、APMに表示されるアプリケーション名の設定が必要です。設定しなくとも計測はできるのですが、newrelic.configで指定しているアプリケーション名(未指定の場合はデフォルトの「My Application」)がアプリケーション名となるため、わかりづらい名前となることが多くなります。アプリケーション名は、設定ファイル、ローカルのnewrelic.configファイルに加え、AgentのAPIをアプリケーションのコードから呼び出すことでも変更できます。

Agnetの有効化(.NET Coreの場合)

.NET Coreの場合、ドキュメントにある通り環境変数としてCORECLR_ENABLE_PROFILING=1を指定します。この環境変数はプロセス起動時に設定している必要があること、およびプロセス単位で設定されていること(ユーザーもしくはシステム環境変数に設定するとすべて.NET Core製のプロセスに対してAgentが計測を行うため)、の両方が必要です。そのため、有効化する方法としては、環境変数の設定と実行ファイルの起動を行うラッパー実行ファイルを作成し、サービスがラッパーを起動するように変更する、というものが考えられます。

また、こちらMicrosoft社のドキュメントに記載が見つからないサポートされない方法であり非推奨ではありますが、レジストリーとしてキーがKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\<service name> (<service name>はWindowsサービス名に置き換え)、値がEnvironment、TypeがREG_MULTI_SZ、データがCORECLR_ENABLE_PROFILING=1というエントリを作成するとこの環境変数が与えれた状態でサービスが起動できることがあります。

Custom Instrumentation(.NET Frameworkおよび.NET Coreの場合)

Agentを有効化しただけではほとんどのWindowsサービスでは計測ができないはずです。.NET AgentはASP.NETなどサポートされたWebフレームワークのアプリケーションではデフォルトで計測できますが、それ以外のアプリケーションでは処理の単位であるトランザクションをcustom instrumentationにて作成する必要があります。custom instrumentationでトランザクションを作成する概要についてはドキュメントを参照してください。

New Relicではトランザクションを1つの処理単位として計測し、その時間変化などを注視します。そのため、どの単位をトランザクションとして計測するかというのはアプリケーションの実装によって決まります。なんらかのイベントをトリガーにしてサービスで処理をする場合、トリガーから起動されるメソッドをトランザクションの起点とするのがひとつの考え方になります。

具体例としてMicrosoftのWindowsサービスアプリを作成するチュートリアルドキュメントを取り上げると、System.Timers.Timer によって1分おきに処理を実行します(=トリガー)。このとき実行されるメソッドがElapsedイベントハンドラに追加されているOnTimerメソッドなので、このOnTimerメソッドをトランザクションの開始点として指定することになります。

トランザクションの起点として設定するメソッドが決まれば、先程のドキュメントにある2つの方法のどちらかで設定を行います。ソースコード修正(およびその後の再ビルド、再デプロイ)が可能であれば属性を対象メソッドに追加する方法が使えます。この方法はその他のAgent APIなどすべての機能が利用できるため、ソースコード修正が可能であればこちらの方法がおすすめです。ソースコード修正が難しい場合はXML設定ファイルを作成します。XML設定ファイルは対象メソッドのアセンブリ名、名前空間つきクラス名、メソッド名がわかれば作成できます。例えば次のようなXMLになります。

<?xml version="1.0" encoding="utf-8"?>

<extension xmlns="urn:newrelic-extension">

  <instrumentation>

      <tracerFactory name="NewRelic.Agent.Core.Tracer.Factories.BackgroundThreadTracerFactory" metricName="OnTimer">

      <match assemblyName="WindowsService1" className="WindowsService1.NRLabService">

        <exactMethodMatcher methodName="OnTimer" />

      </match>

    </tracerFactory>

  </instrumentation>

</extension>

計測する

Agentの有効化とcustom instrumentationを設定するとWindowsサービスが計測できているはずなのでAPMの画面で確認しましょう。以下は毎分同じ処理を起動するサービスの例です。

このようにNew Relicの.NET AgentはWindowsサービスでも計測することが可能です。