AWS

ECS+LaravelのリクエストログをCloudWatch Logs Insightで解析

Laravel

https://github.com/yuukanehiro/ECS-Laravel-CloudWatchLogs-Handson.git

ゴール

Nginxのアクセスログから、実行速度の遅いURL(API)を抽出してパフォーマンス解析できるようにする。

 

構成

srcはLaravelプロジェクトです。

docker-compose.yaml

$ git clone https://github.com/yuukanehiro/ECS-Laravel-CloudWatchLogs-Handson.git
$ cd ECS-Laravel-CloudWatchLogs-Handson
$ ECS-Laravel-CloudWatchLogs-Handson % docker-compose up -d

 

http://localhost

でLaravelの画面が表示されたら成功です。

 

ポイントピックアップ

docker/php/nginx.conf

user www-data;
worker_processes auto;

error_log   /dev/stderr;

pid /var/run/nginx.pid;

events {
  worker_connections  1024;
}

http {
  # ALB Timeout対策
  fastcgi_connect_timeout 120;
  fastcgi_read_timeout    120;
  fastcgi_send_timeout    120;
  keepalive_timeout       120;
  keepalive_requests      100;
  client_header_timeout   60s;
  client_body_timeout     60s;

  include /etc/nginx/mime.types;
  default_type  application/octet-stream;

  log_format ltsv 'time:$time_iso8601\t'
    'remote_addr:$remote_addr\t'
    'request_method:$request_method\t'
    'request_length:$request_length\t'
    'request_uri:$request_uri\t'
    'https:$https\t'
    'uri:$uri\t'
    'query_string:$query_string\t'
    'status:$status\t'
    'bytes_sent:$bytes_sent\t'
    'body_bytes_sent:$body_bytes_sent\t'
    'referer:$http_referer\t'
    'useragent:$http_user_agent\t'
    'forwarded_for:$http_x_forwarded_for\t'
    'forwarded_proto:$http_x_forwarded_proto\t'
    'forwarded_port:$http_x_forwarded_port\t'
    'request_time:$request_time\t'
    'upstream_response_time:$upstream_response_time';

  log_format json escape=json '{'
    '"time": "$time_local",'
    '"host": "$host",'
    '"remote_user": "$remote_user",'
    '"status": "$status",'
    '"server_protocol": "$server_protocol",'
    '"request_method": "$request_method",'
    '"request_uri": "$request_uri",'
    '"query_string": "$query_string",'
    '"request": "$request",'
    '"body_bytes_sent": "$body_bytes_sent",'
    '"request_time": "$request_time",'
    '"upstream_response_time": "$upstream_response_time",'
    '"http_referer": "$http_referer", '
    '"http_user_agent": "$http_user_agent",'
    '"http_x_forwarded_for": "$http_x_forwarded_for",'
    '"http_x_forwarded_proto": "$http_x_forwarded_proto"'
  '}';

  include /etc/nginx/conf.d/*.conf;
}

CloudWatch Logs Insightで扱いやすいようにjson型のログフォーマットを用意しています。

 

バーチャルホストファイルには

server {
    listen 80;
    root /work/public;
    index index.php;
    charset utf-8;
    access_log /dev/stdout json;

    location / {
        root /work/public;
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass app:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

access_log /dev/stdout json;で標準出力に出力するようにして, フォーマットはJSON型を指定しています。

 

ECR作成からDockerイメージのpushまで

 

  • AWS Cliは設定済みとする

 

ECRログイン

$ $(aws ecr get-login --no-include-email --region ap-northeast-1)

 

appのECRリポジトリ作成
$ aws ecr create-repository --repository-name app --region ap-northeast-1
{
    "repository": {
        "repositoryUri": "12312399.dkr.ecr.ap-northeast-1.amazonaws.com/app", 
        "registryId": "12312399", 
        "imageTagMutability": "MUTABLE", 
        "repositoryArn": "arn:aws:ecr:ap-northeast-1:12312399:repository/app", 
        "repositoryName": "app", 
        "createdAt": 1621343423.0
    }
}

webのECRリポジトリ作成
$ aws ecr create-repository --repository-name web --region ap-northeast-1
{
    "repository": {
        "repositoryUri": "12312399.dkr.ecr.ap-northeast-1.amazonaws.com/web", 
        "registryId": "12312399", 
        "imageTagMutability": "MUTABLE", 
        "repositoryArn": "arn:aws:ecr:ap-northeast-1:12312399:repository/web", 
        "repositoryName": "web", 
        "createdAt": 1621343424.0
    }
}

 

 

イメージのビルド
$ docker build -t app -f docker/php/Dockerfile .
$ docker build -t web -f docker/nginx/Dockerfile .

appをECRリポジトリにpush
$ docker tag app:latest 123123999.dkr.ecr.ap-northeast-1.amazonaws.com/app:latest
$ docker push 123123999.dkr.ecr.ap-northeast-1.amazonaws.com/app:latest

webをECRリポジトリにpush
$ docker tag web:latest 123123999.dkr.ecr.ap-northeast-1.amazonaws.com/web:latest
$ docker push 123123999.dkr.ecr.ap-northeast-1.amazonaws.com/web:latest

 

タスク定義

AWSのサービス検索欄で「ECS」と入力し、左のメニューバーの「タスク定義」をクリック

1.「新しいタスク定義の作成」をクリック

2.「EC2」を選択

 

3. 「タスク定義名」を適当に入力
4. ネットワークモードは「default」

タスク実行ロールを設定します。

 


5. 少し下に行き「コンテナの定義」で「コンテナの追加」をクリック

以下の表を参考にコンテナを作成してください。

appコンテナ

  • コンテナ名 app
  • イメージ イメージURL(ECR→app→イメージURLをコピーしてここに貼り付け)
  • メモリ制限 ハード制限(300)
  • 作業ディレクトリ /work
  • DNS サーバー 8.8.8.8
  • ログ設定 Auto-configure CloudWatch Logsにチェック

 

 

webコンテナ

  • コンテナ名 web
  • イメージ イメージURL(ECR→web→イメージURLをコピーしてここに貼り付け)
  • ポートマッピング ホストポート→0,コンテナポート→80,プロトコル→tcp
  • メモリ制限 ハード制限(300)
  • 作業ディレクトリ /work
  • リンク app
  • DNS サーバー 8.8.8.8
  • ログ設定 Auto-configure CloudWatch Logsにチェック

 

コンテナ追加を終えたら「作成」をクリック

 

クラスターの作成

次に左のメニュー欄から「クラスター」選択。

1.「クラスターの作成」をクリック
2.「EC2 Linux + ネットワーキング」を選択
3.「クラスター名」を入力
4.「インスタンスの設定」は以下のように設定

 

プロビジョニングモデル オンデマンドインスタンス
EC2インスタンスタイプ t2.small
インスタンス数 1
キーペア 先ほど作成したキーペアを選択

「作成」をクリックしてください。

無事にクラスターが作成されたら成功です。

 

ALBの作成

ALBの作成を行います。

  1. 「ApplicationLoadBalancer(HTTP,HTTPS)」を選択
  2. 適当に名前を入力
  3. アベイラビリティーゾーンにECSの「VPC ID」と同じものを選択

 

  1. 次の手順を2回押し「3. セキュリティグループの設定」画面へ
  2. 新しいセキュリティグループを作成する(名前は適当に)
  3. 「ルーティングの設定」で名前だけ適当に入力し次の画面へ
  4. 「ターゲットの登録」で下のインスタンスからページ①のインスタンスを選択し「登録済みに追加」クリックし次の画面へ
  5. 「作成」をクリック

無事作成されれば成功です。

 

ECS側のセキュリティグループ設定

 

ALBのセキュリティグループからアクセスをすべて受け入れるようにインバウンドのルールに設定を追加してください。

 

 

タスクの実行

左のメニューの「クラスター」画面に行き、先ほど作ったクラスターの画面に行ってください。

そこから「タスク」→「タスクの実行」をクリック

 

タスクの実行
起動タイプ EC2
タスク定義 先ほど作成したタスクを選択
タスクの数 1

「タスクの実行」をクリック

「ステータス」が「RUNNING」になれば成功です!

ここが「STOPPED」になる場合は、おそらくタスク定義の設定ミスかDocker自体に問題があります。

 

サービスの作成

 

そのまますすめて、クラスターとALBを紐付けてください。

 

 

ALBのDNS名にアクセスしてLaravelの画面が見えたら成功です。

CloudWatch Logs Insightで解析しよう

CloudWatchサービスに移動して「インサイト」を選択します。

「ロググループを選択」でECSのタスク名を選択します。

 

クエリを入力して実行してください。

fields @timestamp, request_time, @message
| sort request_time desc
| limit 20

このクエリは実行速度の遅いリクエストを遅い順から抽出したものになります。

 

他には公式のドキュメントをご覧くださいませ

 

Amazonおすすめ

iPad 9世代 2021年最新作

iPad 9世代出たから買い替え。安いぞ!🐱 初めてならiPad。Kindleを外で見るならiPad mini。ほとんどの人には通常のiPadをおすすめします><

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)