Boxes on assembly lines

従来、New Relic Logsにアプリケーションログを送信するには、Infrastructure Agentやfluentd、fluentbitといったログ転送エージェントが必要でした。最新のAPM AgentにはAPM自身がアプリケーションログを送信できる機能が追加され、デフォルト有効化されています。詳細はこちらのブログを御覧ください。

この機能を使うことで、ログ転送エージェントの設定が不可能であったり難しかったりする、マネージドなPaaS環境であっても、APMさえ設定すればNew Relic Logsにログを送信し、Logs in Contextの機能が利用できるようになりました。そこで今回はAzure App Service (Web Apps)上で動く.NET アプリを例にその設定方法と機能を紹介します。

APM ネイティブログ転送とは

.NET含めてJavaやRubyなどいくつかの言語のAPM Agentで利用可能になったAPM Log Forwardingは、APM AgentがアプリケーションのログをNew Relic Logsに転送する機能です。このときにLogs in Contextに必要な属性も自動で含めることができるため、ログライブラリの設定なしにLogs in Contextが利用できるようになるというメリットもあります。

実際に利用するためには、この機能がサポートしているログライブラリを利用している必要があります。現時点の.NET Agentでは、Log4net、Serilogに加えてMicrosoft.Extensions.Loggingをサポートしています。この3つのライブラリを使っている場合は、これから説明するAPM Agentによるログ転送が利用できます。特にMicrosoft.Extensions.Loggingは、従来の手動によるLogs in Contextの設定ではサポートしておらず、別途SerilogやNLogなどのライブラリを併用する必要があったため、今後は簡単に利用できるようになります。

また、この機能はログ転送はせずに、Logs in Contextに必要な属性だけを付加するlocal decoratingの機能も提供しています。アプリケーションからNew Relic Logsに直接送信することが、ネットワーク制限やパフォーマンス的に許容できない環境でも、手動設定なしでのLogs in Contextの利用につなげることができます。

これらの機能に加えて、アプリケーションがログをどのレベルでどの程度で出力しているかという数値をメトリクスとして利用できるようにもなっています。

APM ネイティブログ転送を設定する

まず、改めてになりますが、アプリケーションで利用しているログライブラリがLog4net、Serilog、Microsoft.Extensions.Loggingのいずれかであることを確認してください。これ以外のライブラリを使っている場合、現時点では利用できません。

今回は、ASP.NET Coreのアプリで、標準で利用できるMicrosoft.Extensions.Loggingを使った以下のようなログコードがあるものと想定します。

public class IndexModel : PageModel
{
    private readonly ILogger<IndexModel> _logger;

    public IndexModel(ILogger<IndexModel> logger)
    {
        _logger = logger;
    }

    public void OnGet(int? id)
    {
        _logger.LogInformation("Hello! APM Logging. query id = {}", id);
        _logger.LogCritical("Ciritcal Log");
        _logger.LogDebug("Debug Log");
        _logger.LogTrace("Trace Log");
        _logger.LogWarning("Warning Log");
        try
        {
            throw new Exception("とある例外");
        }
        catch (Exception e)
        {
            _logger.LogError(e, "例外発生");
        }
    }
}

Microsoft.Extensions.Loggingの出力先の設定などは既存のものから変更する必要はありません。APM Agentが自動的に内部で設定を追加してくれます。必要なのはAPM Agentの設定になります。関連するすべての設定を明示的に行う場合、newrelic.configファイルを以下のように設定します。

<applicationLogging enabled="true">
    <metrics enabled="true" />
    <forwarding enabled="true" maxSamplesStored="10000" />
    <localDecorating enabled="false" />
</applicationLogging>

環境変数で設定する場合は次のようになります。

NEW_RELIC_APPLICATION_LOGGING_ENABLED=true
NEW_RELIC_APPLICATION_LOGGING_METRICS_ENABLED=true
NEW_RELIC_APPLICATION_LOGGING_FORWARDING_ENABLED=true
NEW_RELIC_APPLICATION_LOGGING_FORWARDING_MAX_SAMPLES_STORED=10000
NEW_RELIC_APPLICATION_LOGGING_LOCAL_DECORATING_ENABLED=false

各項目の詳細な説明はドキュメントを参照してください。なお、APM Agentによるログ転送を有効化する設定と、転送せずにローカルへの出力にのみLogs in Contextに必要な情報を付与するlocal decoratingの設定はいずれか片方のみ有効化できます。

https://docs.newrelic.com/docs/apm/agents/net-agent/configuration/net-agent-configuration/#application_logging

以上で設定は完了です。

Azure App Service(Web Apps)での設定

Azure App Serviceでの実際の設定例を見てみましょう。Azure App ServiceにNew Relic .NET Agentを配置する場合、WindowsであればSite Extensionを利用する方法がありますが、今回はLinux環境でも利用できるNuGetパッケージによる方法を紹介します。

計測対象のアプリケーションに、NewRelic.Agent NuGetパッケージを追加します。するとプロジェクトにnewrelicフォルダーが追加され、Agentと設定ファイルが追加されます。このnewrelicフォルダーをアプリと一緒にWeb Appsに配置します。Agentの設定はこの設定ファイルを編集して設定しますが、環境変数でも設定できる項目もあります。必須となるライセンスキーを含め主な設定項目は環境変数でも設定できるため、アプリと同梱されることになる設定ファイルの編集は最低限の設定にとどめておき、アプリの変更が不要な環境変数で設定を行ってみます。今回の例では、設定ファイルはNuGetパッケージにより追加されたデフォルトのままでOKです。

必要な環境変数は以下の通りになります。Web Apps作成時から設定されているデフォルトの環境変数は伏せています。

environment variables

環境変数を追加するとWeb Appsが再起動されるはずです。その後Web Appsにアクセスすると、New Relicにデータが送信されます。

apm summary

左側のメニューの「Logs」をクリックするとアプリケーションから送信しているログが見れます。フレームワークが出力しているログも含まれるので量が増えていますが、コードから出力しているログが確認できます。

logs in apm

また、「Distributed tracing」のメニューからROOTという名前のスパンを表示し、Logsタブを開くと、このトレースから出力されたログが確認できます。これがAPMのLogs in Contextの機能の一つです。

logs in distributed tracing

NRQLを編集すればログレベルごとに表示することも可能です。

log metrics

このように、New Relic APM Agentを使うと、Agentさえ利用可能であれば(そしてサポートしているログライブラリであれば)簡単にログを収集することが可能になりました。Logs in Contextも同時に利用可能になっているのでぜひ試してください。