keyboard_double_arrow_up

Blog X-Tech5エンジニアがお送りするテックブログ
SREやDevOpsをはじめ、インフラエンジニアリングの実践情報を届けします。

New Relic : AWSからのログ転送3パターン

2023年10月18日 

AWS のログ(CloudWatch Logs、S3) を New Relic へ取り込む方法を整理します。

前置き

公式ドキュメントからの引用です。

Forward your logs to New Relic \| New Relic Documentation

Amazon
  We support the following Amazon log forwarders:

– AWS CloudFront plugin
– AWS CloudWatch plugin
– AWS FireLens plugin
– AWS Kinesis Firehose
– AWS Lambda for sending logs from S3

ドキュメントに5つ記載がありますが、”CloudFront plugin” は “Kinesis Firehose” と “Lambda for sending logs from S3” を利用しています。

“FireLens plugin” は AWSサービスではなく、ECS のカスタムルーティングを指していますので今回は割愛します。
ECS からのログ転送パターンは公式ブログで紹介されています。

 

下図の赤枠で囲った3パターンが本稿の対象です。

 

以降、公式ドキュメントの記載順に沿って紹介していきます。

(a) AWS CloudWatch plugin

その名の通りですが、 CloudWatch Logs から New Relic へのログ転送です。
Lambda Function、EC2(CloudWatch Log Agent)、ECS(awslogs) などのログが該当します。

AWS Lambda for sending CloudWatch logs \| New Relic Documentation

AWSサーバーレスアプリケーションリポジトリ で CloudFormation テンプレート "newrelic-log-ingestion" が公開されています。

パラメータのキー名が異なるなどドキュメントとの差異が少しありますが、最低限必須となっている以下のパラメータを指定することで動作します。

  • LICENSE_KEY (NRLicenseKey)
  • LOGGING_ENABLED (NRLoggingEnabled)

オプションの属性を追加するためのパラメータ “NR_TAGS“ は、 Key:Value をセミコロンで区切った文字列です。
以下の様に指定します。

aws_account_id:123456789012;project:demo;environment:dev}

 

AWSサーバーレスアプリケーションリポジトリのソースとなっている GitHub リポジトリ newrelic/aws-log-ingestion を確認すると、 SAM などでの手動デプロイ方法も記載されています。

方法によってパラメータやリソース名などが微妙に異なるので、複数環境へ適用する場合は同様のデプロイ方法を取るのが良いと思います。
    差異の例: SAM テンプレートには Retension の指定が無いのでLogGroupは Never expire (失効しない) で作成されます。Terraform 用テンプレートでは7日が設定されます。

Lambda Permission は "log-group:*" で作成されます。

CloudWatch Log Group から Lambda へのサブスクリプションは前述のテンプレートには含まれていません。
New Relic へ転送したいログに対してトリガーを作成していきます。

公式ドキュメント内に以下の注意点が記載されています。

取り込み機能では、ログサブスクリプションではなく、必ずトリガーを設定してください。Lambdaコンソールでサブスクリプションが設定されている場合、これにより、ログが生成されてNewRelicに転送されるカスケードが発生する可能性があります。

これは、自分自身の Log Group にサブスクリプション設定を行ってしまった場合、ログ生成と転送の連鎖を引き起こしてしまうための記載だと考えます。
(AWSマネジメントコンソール上で、Lambdaコンソールからの Trigger の追加であれば、自分自身のロググループを追加する事ができないようになっています。
対して、CloudWatch Log Group コンソールからの Subscription 設定は行えます。)

例: Lambdaコンソールから自分自身の Trigger 追加はエラーとなる

 

 

(b) AWS Kinesis Firehose

Kinesis Firehose から New Relic への転送です。
CloudWatch Log からも取り込めます。
Kinesis Firehose はスケーリングやバッファリングの機能を備えているため、特別理由が無ければこちらが推奨になると思います。

Stream logs using Kinesis Data Firehose \| New Relic Documentation

手順に沿って Delivery Stream を作成します。
CloudWatch Logs から取り込む場合は、Sourceには "Direct PUT" を指定します。

 

公式ドキュメント内に以下の記載があります。

AWS マネジメント コンソールで追加した任意のキー/値のペアは、New Relic で使用できる属性/値のペアになります。Kinesis Data Firehose は、これらのキーと値のペアを各 HTTP 呼び出しに含めます。これらのKinesis Firehose パラメータは、宛先を特定して整理するのに役立ちます。

これは Delivery Stream の "Parameters" の Key:Value を指しています。

"logtype" を指定することで、New Relic でのログ解析に組み込みルールを利用する事ができます。
カスタムルールを使用する場合でもログの振り分けを行えるよう、 logtype を設定することが推奨されます。

logtype 別に Delivery Stream を作成するとログ解析がしやすくなると思いますが、 Quota との兼ね合いもあるので Delivery Stream の作成単位は悩みどころです。

また、Firehose の名称 DeliveryStreamName は最大 64 文字の文字数制限があります。対して CloudWatch Logs の LogGroupName は最大 128 文字です。
Log Group と同名で Delivery Stream を作成したくなりますが、文字数制限に抵触しやすいので注意です。

(a) と (b) との取り込み結果比較

同一ログを (a), (b) 両方に流し比較してみます。

ログの内容に大きな違いはありません。

LogGroup や LogStream はキーが異なりますが、いずれも設定されます。

どの方式で送信されたかは以下の属性で判別ができます。

Key Value(a) Value(b)
newrelic.source api.logs api.logs.awsFirehose
plugin.type lambda aws-firehose

ログへの属性追加はいずれも送信元の設定で行なえます。

  • (a) ・・・Lambda Function の環境変数(NR_TAGS)
  • (b) ・・・Kinesis Firehose のパラメータ

 

(c) AWS Lambda for sending logs from S3

S3 Bucket から New Relic への転送です。
ELBアクセスログ、CloudFront標準ログなどが該当します。

AWS Lambda for sending logs from S3 \| New Relic Documentation

AWSサーバーレスアプリケーションリポジトリ で CloudFormation テンプレート "NewRelic-log-ingestion-s3" が公開されています。 

AWSサーバーレスアプリケーションリポジトリのソースとなっている GitHub リポジトリは、newrelic/aws_s3_log_ingestion_lambda です。手動デプロイは Serverless Framework での方法がドキュメントに記載されています。

最低限必須となっている以下のパラメータを指定することで動作します。

  • Application name
  • NRLicenseKey

Retension の指定が無いのでLogGroupは Never expire (失効しない) で作成されます。

NRLogType を指定することで logtype 属性を設定できます。
logtype 別に作成したい所ですが、FunctionName が固定で記述されているためテンプレートの修正が必要になります。Runtime バージョンも python3.8 で、少々古いです。

オプションの属性を追加するためのパラメータ “AdditionalAttributes” は JSON 文字列です。

“(Optional) A string containing json object(string,string). These attributes will be added to New Relic payload.”

以下の様に指定します。

{"aws_account_id": "123456789012", "project": "demo", "environment": "dev"}

SourceLogBucket へログ出力を行うか、転送するS3バケットへS3 Event を作成します。

New Relic へ転送したいログが含まれるS3バケットに対してトリガーを作成していきます。

S3イベントが付与されたSourceLogBucketが含まれているので、SourceLogBucketにログファイルを格納する事でも転送されます。

(c) の取り込み結果

 

どの方式で送信されたかは以下の属性で判別ができます。

Key Value
newrelic.source api.logs
plugin.type s3-lambda

まとめ

テンプレートを利用する場合は利用する環境に合わせて適宜修正・更新しましょう。

いずれの方式でも logtype やその他の属性追加が可能です。

属性 (a) (b) (c)
logtype Lambda Function の
環境変数 NR_TAGS
Delivery Stream の
Parameters
Lambda Function の
環境変数 NRLogType
その他追加属性 同上 同上 Lambda Function の
環境変数 AdditionalAttributes

 

どの方式で取り込まれたかは以下の属性が付与されるため判別可能です。

Key Value(a) Value(b) Value(c)
newrelic.source api.logs api.logs.awsFirehose api.logs
plugin.type lambda aws-firehose s3-lambda


留意点として、New Relic上では、ログ内の日時ではなく取り込み処理の日時になります。
特に (c) の場合は処理の仕組み上、乖離が大きくなるため注意が必要です。