CoffeeScript で書かれた hubot が ECS + Fargate 上で稼働中なのですが、これに Datadog の監視を入れてみます
ChatWork 経由で hubot に命令しているのですが、ChatWork のメンテナンス等があるとメンテナンス後も hubot がエラーで落ちたままになったことがあったので、hubot を監視して異常があれば、Slack に通知する機能作ります
コンテナーのメトリクスを取得
Datadog Agent をインストール
まずは、Datadog 管理画面の Integrations から Amazon Fargate をインストール
次はホストに Datadog Agent をインストールします
ECS + Fargate の場合は、Datadog Agent のコンテナーを作成し、ECS のタスク定義内で設定します
今回は AWS コンソール上から作業します
タスク定義の新しいリビジョンを作成します
コンテナーの追加をクリックして、以下の内容を設定します
項目名 | 設定値 |
---|---|
コンテナー名 | datadog-agent |
イメージ | datadog/agent:latest |
環境変数 | Key=DD_API_KEY, Value=Datadog の API Key |
環境変数 | Key=ECS_FARGATE, Value=true |
Datadog のドキュメントでは、メモリ制限 (MiB)や CPU ユニット数も細かく指定しています
ただし、AWS の開発ガイドを見てみると、コンテナーのメモリはオプションで、
「ほとんどのユースケースでは、タスクレベルでこれらのリソースを指定するだけで十分です。」
って書いてあるので、今回は設定しませんでした
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/AWS_Fargate.html
CPU ユニット数も 1vCPU なら 1024CPU ユニット以内の数値であれば、設定できますが、Fargate の場合は、こちらもオプションだったので、設定しませんでした
この辺は使いながら、調整しようと思います
タスク定義更新後は、ECS のサービスをタスク定義の新しいリビジョンを使うように更新します
IAM ポリシーの設定
Datadog の Amazon Web Services Integration に設定しているロールのポリシーに以下の権限を追加します
ecs:ListClusters
ecs:ListContainerInstances
ecs:DescribeContainerInstances
確認
Datadog の管理画面からInfrastructure -> Containers
に移動し、アプリケーションの CPU やメモリ等のメトリクス情報が取得できていたら成功です
hubot のプロセス監視
先ほど作成したdatadog-agent
コンテナーの環境変数に以下を追加すれば、プロセス情報の収集ができるようになります
Key | Value |
---|---|
DD_PROCESS_AGENT_ENABLED | true |
Datadog の管理画面からInfrastructure -> Processes
に移動し、プロセス情報が取れていたら成功です
ただ、今回は有用な情報は取れませんでした
hubot コンテナーのログ監視
色々調べたのですが、hubot が CoffeeScript というレガシーな言語を使っているという縛りもあり、アプリ側から何か仕込むことが難しかったので、結局コンテナー内のログを全部 Datadog へ飛ばすことにしました
ログドライバーを FireLens に変更
FireLens は ECS で使えるログルーターであり、ログの出力先をルーティングできます
ここでは FireLens から Fluent Bit にログを転送し、Fluent Bit が Datadog をサポートしているので、Fluent Bit から Datadog にログを転送します
hubot が動いている方のコンテナーのログドライバーをawsfirelens
に設定し、以下の Key/Value を設定します
Key | Value |
---|---|
Name | datadog |
Host | http-intake.logs.datadoghq.com |
TLS | on |
apikey | Datadog の API Key |
dd_service | 対象のサービス名 |
dd_source | 対象のミドルウェア名 |
provider | ecs |
上記で保存すると、log_router
というコンテナー名でaws-for-fluent-bit
イメージのコンテナーがタスク定義内に追加されます
これを独自の Fluentd や Fluent Bit イメージを使うように書き換えることもできます
この Fluent Bit を使って Datadog にログを転送します
他のやり方として、awslogs
ログドライバーでも Lambda を使って、Datadog にログを転送するやり方もありますが、Datadog では FireLens を使ったやり方を推奨しているみたいです
確認
Datadog の管理画面からLogs
に移動し、ログが出力されていたら成功です
Slack 通知
Datadog の Integrations から Slack を追加し、Webhook URL と通知先の Channel 名を設定しておきます
Datadog 管理画面のMonitors -> New Monitor -> Logs
に移動します
hubot から ChatWork に対してポーリングしているので、hubot と ChatWork 間でエラーが発生しているとエラーログを出力し続けます
ポーリングの回数は環境変数の HUBOT_CHATWORK_API_RATE の設定値によって変動しますが、とりあえず以下のように直近 15 分で 20 件より多くのログが出力されたら、Slack へ通知するようにしました
logs("service:hubot").index("*").rollup("count").last("15m") > 20
これで上手くいかなかったら、また考えます
追記 - 2020/11/13
ログの Facet を追加して、以下のように 500 系のエラーが出た場合に通知するように変更した
logs("service:stg-hubot @log:(*ERROR* *Chatwork* *50*)").index("*").rollup("count").last("15m") > 0
参考
https://docs.datadoghq.com/integrations/ecs_fargate/?tab=fluentbitandfirelens