New Relic : AWSからのログ転送3パターン
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) の場合は処理の仕組み上、乖離が大きくなるため注意が必要です。