CloudWatch LogsのログをNewRelicへ取り込みアラート設定する

こんにちは、香田です。

今回はCloudWatch LogsのログをNewRelicへ取り込みアラート設定する方法について紹介していきます。

ログ取り込み先のNewRelicは無料で開始可能です。事前に下記を参考にサインアップしてみてください。

NewRelicへのログ取り込み

NewRelicではログ管理機能を提供しており、New Relic Infrastructure AgentやFluentdなどのログ転送プラグイン、New Relic Log APIを使用しHTTP経由でのログ取り込みなどが可能です。

ログの取り込みは、下記のようにCloudWatch Logsに送信されたログに対して、サブスクリプションフィルターとLambda使用した方法を紹介していきます。

NewRelicへログを取り込むLambdaについては、公式で提供されている下記のTerraform Moduleを使用し設定していきます。

Terraform AWSプロバイダの設定

AWSのリソース作成用にAWSプロバイダを設定します。

provider "aws" {
  region = "ap-northeast-1"
}

NewRelic log ingestionの作成

NewRelicにて提供されているnewrelic-log-ingestionをmoduleとして定義していきます。

nr_license_keyにはNew Relic License Keyを発行し設定してください。

module "newrelic_log_ingestion" {
  source                       = "github.com/newrelic/aws-log-ingestion"
  service_name                 = "newrelic-log-ingestion"
  nr_license_key               = <New Relic License Key>
  nr_logging_enabled           = true
  lambda_archive               = "src/newrelic-log-ingestion.zip"
  lambda_log_retention_in_days = 14
}

CloudWatch Logsの作成

CloudWatch Logsを作成し、サブスクリプションフィルターとしてmoduleで定義したnewrelic-log-ingestionを設定します。

resource "aws_cloudwatch_log_group" "this" {
  name              = "example"
  retention_in_days = 14
}

resource "aws_cloudwatch_log_subscription_filter" "this" {
  destination_arn = module.newrelic_log_ingestion.function_arn
  log_group_name  = aws_cloudwatch_log_group.this.name
  distribution    = "ByLogStream"
  name            = "newrelic"
  filter_pattern  = ""
}

terraform applyを実行しAWSリソースを作成します。

$ terraform init
$ terraform apply

ログイベントを送信

作成したロググループへテストのログイベントを送信します。

log_stream_name=test-stream-$(date +%s)

aws logs create-log-stream \
    --log-group-name example \
    --log-stream-name ${log_stream_name}

aws logs put-log-events \
    --log-group-name example \
    --log-stream-name ${log_stream_name} \
    --log-events timestamp=$(gdate +%s%3N),message="Hello CloudWatch Logs"

下記のようにCloudWatch Logsでログが確認できるはずです。

NewRelicへのログ取り込みの確認

ロググループへ設定したサブスクリプションフィルターのLambdaを経由し、New Relicへ取り込まれているか確認します。

取り込まれたログはLogs UIより、下記のように確認可能です。

Logs UIの使用方法については下記を参考にしてみてください。

NewRelicでログのアラート設定

次に取り込んだログに対して、Terraformを利用しNewRelicでアラートを設定していきます。

公式で提供されているTerraform NewRelicプロバイダーを設定します。

api_keyにはNewRelicのユーザーキーを発行し設定してください。

account_idにはNewRelicのアカウントIDを設定します。

terraform {
  required_providers {
    newrelic = {
      source = "newrelic/newrelic"
    }
  }
}

provider "newrelic" {
  api_key = <User key>
  account_id = <New Relic account ID>
  region     = "US"
}

アラートポリシーを設定します。通知先としてSlackチャネルを設定します。

resource "newrelic_alert_channel" "slack" {
  name = "example"
  type = "slack"

  config {
    channel = "monitoring"
    url     = "http://example-org.slack.com"
  }
}

resource "newrelic_alert_policy" "this" {
  name                = "example-policy"
  incident_preference = "PER_CONDITION_AND_TARGET"

  channel_ids = [
    newrelic_alert_channel.slack.id,
  ]
}

アラートの条件を設定します。

事前に作成したロググループにてerrorという文字列が含まれる場合、アラート通知するように設定します。

resource "newrelic_nrql_alert_condition" "this" {
  name                           = "example"
  policy_id                      = newrelic_alert_policy.this.id
  type                           = "static"
  enabled                        = true
  aggregation_method             = "event_flow"
  aggregation_window             = 60
  aggregation_delay              = 120
  expiration_duration            = 0
  fill_option                    = "none"
  fill_value                     = 0
  open_violation_on_expiration   = false
  close_violations_on_expiration = false
  value_function                 = "SINGLE_VALUE"
  violation_time_limit_seconds   = 600

  nrql {
    query = <<-EOT
    SELECT count(*) FROM Log
    WHERE `aws.logGroup` = '${aws_cloudwatch_log_group.this.name}'
    AND `message` LIKE '%error%'
    EOT
  }

  critical {
    operator              = "above"
    threshold             = 1
    threshold_duration    = 60
    threshold_occurrences = "all"
  }
}

terraform applyを実行します。

$ terraform init
$ terraform apply

NewRelic ログのアラート通知確認

設定した条件でSlackへアラート通知されるか確認していきます。

ロググループへ下記のようなログイベントを数回送信します。

log_stream_name=test-stream-$(date +%s)

aws logs create-log-stream \
    --log-group-name example \
    --log-stream-name ${log_stream_name}

aws logs put-log-events \
    --log-group-name example \
    --log-stream-name ${log_stream_name} \
    --log-events timestamp=$(gdate +%s%3N),message="Hello CloudWatch Logs Error"

下記のようにSlackへ通知されることが確認できれば成功です。

さいごに

CloudWatch LogsのログをNewRelicへ取り込みアラート設定する方法如何でしたでしょうか?

アラート条件については、下記を参考にすると目的に応じたアラート条件が設定できるかと思います。

最後までご覧いただきありがとうございます。

SNSでもご購読できます。