20190506のlaravelに関する記事は6件です。

Sentryを使ってエラー監視

新しい話題ではないですが、エラーログのトラッキングサービスにSentryというものがあるので使ってみました。導入手順をまとめておきます。

環境

Laravel5.5

Sentryの仕組み

Sentryはアプリケーションサーバに出力されたログファイルを監視するのではなく、アプリケーション側にSentryにエラー情報を送信する仕組みを組み込む方式を取っています。
そのためエラーの情報だけがSentryに蓄積され、それらの傾向を見たり対策を立てることができます。
issueとしてSentry上でタスクとして管理することもできるため、エラー専用のタスク管理ツールとしても活用できます。

ただし、無料プランではプロジェクトの中にメンバーを追加できないため共有アカウントを使う等しないと複数人での利用は難しいです。本格的に使うなら有料プランが必須になりそうでした。

導入方法

sign up後、プロジェクトにLaravelを選んで作成します。
スクリーンショット 2019-05-06 19.42.44.png

すると導入に必要なコードが出力されるのでそれに沿って作業を進めます。

composer require sentry/sentry-laravel:1.0.2

次にエラー内容を送信する処理を書きます。

App\Exceptions\Handler.php
public function report(Exception $exception)
{
    if (app()->bound('sentry') && $this->shouldReport($exception)){
        app('sentry')->captureException($exception);
    }

    parent::report($exception);
}    

次に、Sentryの設定ファイル下記コマンドで生成します。

php artisan vendor:publish --provider="Sentry\Laravel\ServiceProvider"

最後に、.envにURLを指定します。

SENTRY_LARAVEL_DSN=https://XXXXXXXXXXXXXX

これで設定は完了です。

動作

動作確認のため、エラーを起こして見るとイベントが登録されているはずです。

メソッド名をちょっと変更して存在しないメソッド呼び出しにしたときのエラーです。
スクリーンショット 2019-05-06 22.56.55.png

エラーの箇所と内容をわかりやすく表示してくれています。

stacktraceもしっかり表示してくれます。
スクリーンショット 2019-05-06 23.02.00.png

そのほかにもリクエスト送信元の情報もあり

  • リクエスト元のipアドレス
  • 閲覧に使われたブラウザ
  • 稼働中のPHPのバージョン
  • 動作環境(stgかproductionか)

などを一箇所で見ることができます。
テキストログを眺めるよりは圧倒的に見やすく、検証の効率は良さそうです。

通知

Slackとの連携機能も可能です。
自分が作ったグループの設定ページからIntegrationメニューを選んだ先で選択可能です。

スクリーンショット 2019-05-06 23.10.22.png

ここで設定したら次いはAlertの設定です。
Laravelのプロジェクトページに移動した後のメニュー画面からAlertの設定画面に行きます。

Alertは基準となるイベントと閾値を選択することで設定できます。

とにかく何かエラーが起きたら通知して見るためには

スクリーンショット 2019-05-06 23.14.39.png

のように設定すれば良いです。これはerrorかfatalなログが送られてきたら発火する設定です。

また、この下にslackの通知設定も出てくるので、そこで通知したいグループを指定したらOKです。

通知内容はTagに含まれる内容であればカンマ区切りで指定可能です。
例えば、

environment,level,url,transaction

など。取得できる内容はエラー詳細ページにTagの一覧は載ってるのでそこから選べば良いです。

最後に

無料枠で試しましたが、Sentryはtextログと比べてエラーの調査をしやすくなるだろうなと思いました。有料版でしか使えない機能もたくさんあるので使える機会があったらいいなあと思った次第です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

LaravelのRelationshipsを取得する際の注意点(selectで外部キーも指定しないとnull)

LaravelでCityモデルにPrefectureモデルへの関連が定義されているとします。

<?php
declare(strict_types=1);

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class City extends Model
{
    // 略

    public function prefecture()
    {
        return $this->belongsTo('App\Models\Prefecture')->open();
    }
}

以下のように、データを取得した後で関連データを参照すると、参照のたびにSQLが発行されます。
N+1問題というやつですね。

$cities = City::get();
foreach($cities as $city) {
    var_dump($city->prefecture);
}

対応として、Eager Loadingと呼ばれる事前データ取得処理をおこないます。
Laravelではwithメソッドでモデルを指定します。

$cities = City::with('Prefecture')->get();
foreach($cities as $city) {
    var_dump($city->prefecture);
}

// 複数の場合は配列もしくは複数回withメソッドを呼び出します。
$cities = City::with(['Prefecture', 'Towns'])->get();
$cities = City::with('Prefecture')->with('Towns')->get();

さらに、不要なカラムはいらないので、selectメソッドを追加してみます。

$cities = City::select('code')->with('Prefecture')->get();
foreach($cities as $city) {
    var_dump($city->prefecture);
}

ぎゃー

NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL (略)

外部キーも指定しないとダメなようです

$cities = City::select(['code', 'prefecture_id'])->with('Prefecture')->get();
foreach($cities as $city) {
    var_dump($city->prefecture);
}

ということで、関連テーブルをEagar Lodingで取得する際にselectメソッドを組み合わせる場合は、外部キーもselectに指定する必要があるという覚書でした。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CloudFormationでLaravel5.5が動く環境をEC2(Ubuntu18.04)上に作ったときのまとめ

GWだったので趣味で開発してるLaravelプロジェクトをEC2で動かすために必要な環境をCloudFormationで立ててみました。その時に必要となった知識をまとめておきます。

必要な環境

  • OS

    • Ubuntu18.04
  • 必要サーバ

    • EC2インスタンス1台
  • インストールが必要なもの(ざっくり)

    • php7.2
    • php-fpm
    • composer
    • Laravelの動作に必要なPHPのライブラリ群
    • nginx
  • 追加で必要なサービス

    • Elastic IP
  • Security Groupの要件

    • ssh接続の許可
    • http接続の許可

CloudFormationによるインスタンスの管理

CloudFormationには初期化コマンドを実行するための仕組みをpythonスクリプトで提供していますが、Ubuntu18.04にはデフォルトで備えられていないので自前インストールします。pipを使って下記のコマンドで実現できました。

sudo apt-get update
sudo apt-get -y install python-pip
pip install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz
sudo cp -a /usr/local/init/ubuntu/cfn-hup /etc/init.d/cfn-hup
chmod u+x /etc/init.d/cfn-hup
sudo update-rc.d cfn-hup defaults
sudo service cfn-hup start

これにより

  • テンプレート内でパッケージインストールなどをパラメータで指定して実行(cfn-init)
  • cfn-initで実行したコマンドのステータスを見て通達(cfn-signal)
  • テンプレート更新によるstack更新を検知するデーモン(cfn-hup)

が利用可能になります。他にもありますが、使ってないので触れません。

cfn-init

cfn-init ヘルパースクリプトは、AWS::CloudFormation::Init キーからテンプレートメタデータを読み取り、それに応じて様々な処理を実行します。(公式ドキュメント抜粋)
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cfn-init.html

実行コマンド例

sudo /usr/local/bin/cfn-init -v --stack "YourStackName" --resource WebApp --configsets Install --region "YourRegion"

設定の読み込み

CloudFormationの中にResources.WebApp.Metadata.AWS::CloudFormation::Initという宣言を書き、その要素として実行コマンドを記述できます。
configSetsというパラメータに実行するtaskをまとめて指定することができるので、ここに必要なtaskを登録しましょう。

"Resources": {
    "WebApp": {
        "Metadata": {
            "AWS::CloudFormation::Init": {
                "configSets": {
                    "Install": [
                        "taskName1",
                        "taskName2",
                        "..."
                    ]
                },
                "taskName1": {
                    "..."
                },
                "taskName2": {
                    "..."
                },
                "..."
            }
        }
    }    
}

taskに指定できるコマンドにはいくつか種類があるので今回用いたものを書いていきます。

公式ドキュメントはこちら
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-init.html

packageインストール

aptコマンドを使ったパッケージインストールは下記のように記述すると必要なパッケージをインストールできます。

"taskName": {
    "packages": {
        "apt": {
            "nginx": [],
            "php7.2": [],
            "php-fpm": [],
            "php7.2-mysql": [],
            "php7.2-zip": [],
            "php7.2-mbstring": [],
            "php7.2-dom": [],
            "php7.2-curl": [],
            "composer": []
        }
    }
}

ファイル作成

例えばnginxの設定ファイルを作成したければ下記のような記述をすればパーミッションを指定した上で作成が可能です。

区切り文字を改行コードで指定しているため、複数行に渡って記述することができます。

"taksName": {
     "files": {
        "/etc/nginx/nginx.conf": {
            "content": {
                "Fn::Join": [
                    "\n",
                    [
                        "your settings",
                        "write here"
                    ]
                ]
            },
            "mode": "000400",
            "owner": "root",
            "group": "root"
        }
    }
}

コマンド実行

これは自由度が高いです。好きなコマンドを実行できます。

"taskName": {
    "commands": {
        "makeConfDir": {
            "command" : "sudo mkdir -p /etc/nginx/common"
        }
    }
}

プロセス起動

services キーを使用すると、インスタンスが起動されるときに有効化または無効化する必要のあるサービスを定義できます。(公式ドキュメント抜粋)

Linuxではsysvinitキーを指定することで初回起動時の振る舞いを指定できるようです。

用いたオプションの意味は下記のとおりです。
enabled: 起動時にサービスを自動的に開始させるかどうか
ensureRunning: cfn-init が終了した後でサービスを実行するかどうか
files: 読み込む設定ファイルのリスト

"taskName": {
     "services": {
         "sysvinit": {
             "cfn-hup": {
                 "enabled": "true",
                 "ensureRunning": "true",
                 "files": [
                     "/etc/cfn/cfn-hup.conf",
                     "/etc/cfn/hooks.d/cfn-auto-reloader.conf"
                 ]
             }
         }
     }
}

ログの場所

重要な情報が入ってるのでCloudFormationを使う時はこのログファイルを見ることになると思います。

# 詳細なログ
/var/log/cfn-init.log
# 結果だけ出力されるログ
/var/log/cfn-init-cmd.log

cfn-signal

cfn-initの実行後のステータスを引数に与えて使うことで状態を追跡できるようになります。
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cfn-signal.html

ドキュメントの通り、下記のように使って、cfn-init実行後のステータス$?を渡して実行します。


"UserData": {
    "Fn::Base64": {
        "Fn::Join": [
            "",
            [
                "#!/bin/bash -x\n",
                "# Install the files and packages from the metadata\n",
                "/opt/aws/bin/cfn-init -v ",
                "         --stack ",
                {
                    "Ref": "AWS::StackName"
                },
                "         --resource MyInstance ",
                "         --region ",
                {
                    "Ref": "AWS::Region"
                },
                "\n",
                "# Signal the status from cfn-init\n",
                "/opt/aws/bin/cfn-signal -e $? ",
                "         --stack ",
                {
                    "Ref": "AWS::StackName"
                },
                "         --resource MyInstance ",
                "         --region ",
                {
                    "Ref": "AWS::Region"
                },
                "\n"
            ]
        ]
    }
}

cfn-hup

cfn-hupは2つの設定ファイルを用いて動作させます。
/etc/cfn/cfn-hup.conf: 変更の検知
/etc/cfn/hooks.d/cfn-auto-reloader.conf: hook処理の定義

/etc/cfn/cfn-hup.confのintervalは変更があったかを調べる周期なので、開発中は短くしておくと便利です(デフォルト15分)。
hookの設定ファイルにupdateされたらcfn-initを実行するように書いておきます。

"files": {
    "/etc/cfn/cfn-hup.conf": {
        "content": {
            "Fn::Join": [
                "",
                [
                    "[main]\n",
                    "stack=",
                    {
                        "Ref": "AWS::StackId"
                    },
                    "\n",
                    "region=",
                    {
                        "Ref": "AWS::Region"
                    },
                    "\n",
                    "interval=5",
                    "\n"
                ]
            ]
        },
        "mode": "000400",
        "owner": "root",
        "group": "root"
    },
    "/etc/cfn/hooks.d/cfn-auto-reloader.conf": {
        "content": {
            "Fn::Join": [
                "",
                [
                    "[cfn-auto-reloader-hook]\n",
                    "triggers=post.update\n",
                    "path=Resources.WebApp.Metadata.AWS::CloudFormation::Init\n",
                    "action=/usr/local/bin/cfn-init -v ",
                    "         --stack ",
                    {
                        "Ref": "AWS::StackName"
                    },
                    "         --resource WebApp ",
                    "         --configsets Install ",
                    "         --region ",
                    {
                        "Ref": "AWS::Region"
                    },
                    "\n",
                    "runas=root\n"
                ]
            ]
        },
        "mode": "000400",
        "owner": "root",
        "group": "root"
    }
}

設定ファイルのサンプル

Laravelはcomposerを使っており、設定ファイルはjson形式なのでCloudFormationの設定ファイルもjsonに合わせています。
本当はコメント使えないですが、便宜的に追加してます。

SecurityGroupやElastic IPについては特に困ったことは無かったので説明しませんでしたが、このサンプルに含まれています。

{
   "Resources": {
        # ssh接続するための設定
        "SSHGroup": {
            "Type": "AWS::EC2::SecurityGroup",
            "Properties": {
                "GroupDescription": "Enable SSH access via port 22",
                "SecurityGroupIngress": [
                    {
                        "IpProtocol": "tcp",
                        "CidrIp": "0.0.0.0/0",
                        "FromPort": "22",
                        "ToPort": "22"
                    }
                ]
            }
        },
        # httpとhttps通信を許可する設定
        "httpGroup": {
            "Type": "AWS::EC2::SecurityGroup",
            "Properties": {
                "GroupDescription": "Enable http access via port 80",
                "SecurityGroupIngress": [
                    {
                        "IpProtocol": "tcp",
                        "CidrIp": "0.0.0.0/0",
                        "FromPort": "80",
                        "ToPort": "80"
                    }
                ]
            }
        }, 
        # IPアドレスを固定するために割り当てる
        "WebServerEip": {
            "Type": "AWS::EC2::EIP",
            "Properties": {
                "InstanceId": {
                    "Ref": "WebApp"
                }
            }
        },
        # 立ち上げるEC2インスタンスの設定
        "WebApp": {
            "Type": "AWS::EC2::Instance",
            "Metadata": {
                "AWS::CloudFormation::Init": {
                    "configSets": {
                        "Install": [
                            "Install",
                            "SetupNginx",
                            "StartNginx"
                        ]
                    },
                    "Install": {
                        # 必要なパッケージのインストール
                        "packages": {
                            "apt": {
                                "nginx": [],
                                "php7.2": [],
                                "php-fpm": [],
                                "php7.2-mysql": [],
                                "php7.2-zip": [],
                                "php7.2-mbstring": [],
                                "php7.2-dom": [],
                                "php7.2-curl": [],
                                "composer": []
                            }
                        },
                        # 初期化時に実行するコマンド
                        "files": {
                            "/etc/cfn/cfn-hup.conf": {
                                "content": {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "[main]\n",
                                            "stack=",
                                            {
                                                "Ref": "AWS::StackId"
                                            },
                                            "\n",
                                            "region=",
                                            {
                                                "Ref": "AWS::Region"
                                            },
                                            "\n",
                                            # 開発中はチェック頻度短くしたほうが楽(デフォルト15分)
                                            "interval=5",
                                            "\n"
                                        ]
                                    ]
                                },
                                "mode": "000400",
                                "owner": "root",
                                "group": "root"
                            },
                            # stackを更新した時に反映させるためのデーモンの設定
                            "/etc/cfn/hooks.d/cfn-auto-reloader.conf": {
                                "content": {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "[cfn-auto-reloader-hook]\n",
                                            "triggers=post.update\n",
                                            "path=Resources.WebApp.Metadata.AWS::CloudFormation::Init\n",
                                            "action=/usr/local/bin/cfn-init -v ",
                                            "         --stack ",
                                            {
                                                "Ref": "AWS::StackName"
                                            },
                                            "         --resource WebApp ",
                                            "         --configsets Install ",
                                            "         --region ",
                                            {
                                                "Ref": "AWS::Region"
                                            },
                                            "\n",
                                            "runas=root\n"
                                        ]
                                    ]
                                },
                                "mode": "000400",
                                "owner": "root",
                                "group": "root"
                            }
                        },
                        # cfn-hupを初期起動させる
                        "services": {
                            "sysvinit": {
                                "cfn-hup": {
                                    "enabled": "true",
                                    "ensureRunning": "true",
                                    "files": [
                                        "/etc/cfn/cfn-hup.conf",
                                        "/etc/cfn/hooks.d/cfn-auto-reloader.conf"
                                    ]
                                }
                            }
                        }
                    },
                    # nginxの設定に必要なファイルやディレクトリを作成
                    "SetupNginx": {
                        # ここで作ったディレクトリはnginxの設定ファイルでincludeする必要がある
                        "commands": {
                            "makeConfDir": {
                                "command" : "sudo mkdir -p /etc/nginx/common"
                            }
                        },
                        "files": {
                            "/etc/nginx/nginx.conf": {
                                "content": {
                                    "Fn::Join": [
                                        "\n",
                                        [
                                            "your settings"
                                        ]
                                    ]
                                },
                                "mode": "000400",
                                "owner": "root",
                                "group": "root"
                            },
                            # サービス毎に分けて管理する
                            "/etc/nginx/sites-available/your_site.conf": {
                                "content": {
                                    "Fn::Join": [
                                        "\n",
                                        [
                                            "your_settings"
                                        ]
                                    ]
                                },
                                "mode": "000400",
                                "owner": "root",
                                "group": "root"
                            },
                            # php-fpmの設定ファイルを分けておく
                            "/etc/nginx/common/php_fastcgi.conf": {
                                "content": {
                                    "Fn::Join": [
                                        "\n",
                                        [
                                            "your_settings"
                                        ]
                                    ]
                                },
                                "mode": "000400",
                                "owner": "root",
                                "group": "root"
                            },
                            "/etc/nginx/common/general.conf": {
                                "content": {
                                    "Fn::Join": [
                                        "\n",
                                        [
                                            "your settings"
                                        ]
                                    ]
                                },
                                "mode": "000400",
                                "owner": "root",
                                "group": "root"
                            }
                        }
                    },
                    # 起動
                    "StartNginx": {
                        "commands" : {
                            "start": {
                                "command" : "sudo systemctl start nginx"
                            }
                        }
                    }
                }
            },
            "Properties": {
                # Ubuntu18.04のami
                "ImageId": "ami-0eb48a19a8d81e20b",
                "InstanceType": {
                    "Ref": "InstanceType"
                },
                "KeyName": {
                    "Ref": "KeyName"
                },
                "SecurityGroupIds": [
                    {
                        "Ref": "SSHGroup"
                    },
                    {
                        "Ref": "httpGroup"
                    }
                ],
          # 最初に実行するコマンドの指定
                "UserData": {
                    "Fn::Base64": {
                        "Fn::Join": [
                            "",
                            [
                                "#!/bin/bash -xe\n",
                                "sudo apt-get update\n",
                                "sudo apt-get -y install python-pip\n",
                                # cfn-hupが使えるようにする
                                "pip install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n",
                                "sudo cp -a /usr/local/init/ubuntu/cfn-hup /etc/init.d/cfn-hup\n",
                                "chmod u+x /etc/init.d/cfn-hup\n",
                                "sudo update-rc.d cfn-hup defaults\n",
                                "sudo service cfn-hup start\n",
                                "# Install the files and packages from the metadata\n",
                                "sudo /usr/local/bin/cfn-init -v ",
                                "         --stack ",
                                {
                                    "Ref": "AWS::StackName"
                                },
                                "         --resource WebApp ",
                                "         --configsets Install ",
                                "         --region ",
                                {
                                    "Ref": "AWS::Region"
                                },
                                "\n",
                                # エラーハンドリング用
                                "# Signal the status from cfn-init\n",
                                "sudo /usr/local/bin/cfn-signal -e $? ",
                                "         --stack ",
                                {
                                    "Ref": "AWS::StackName"
                                },
                                "         --resource WebApp ",
                                "         --region ",
                                {
                                    "Ref": "AWS::Region"
                                },
                                "\n"
                            ]
                        ]
                    }
                }
            }
        }
    },
    # stack作成時にオプション選択するパラメータを指定
    "Parameters": {
        "KeyName": {
            "Description": "Name of an existing EC2 KeyPair to enable SSH access to the web server",
            "Type": "String",
            "Default": "your_key"
        },
        "InstanceType": {
            "Description": "WebServer EC2 instance type",
            "Type": "String",
            "Default": "t2.micro",
            "AllowedValues": [
                "t1.micro",
                "t2.nano",
                "t2.micro"
            ],
            "ConstraintDescription": "must be a valid EC2 instance type."
        }
    },
    # stackの状態を見た時に表示される内容
    "Outputs": {
        "WebServerIpAddress": {
            "Value": {
                "Fn::GetAtt": [
                    "WebApp",
                    "PublicIp"
                ]
            },
            "Description": "IP Address of WebServer"
        },
        "WebServerAvailabilityZone": {
            "Value": {
                "Fn::GetAtt": [
                    "WebApp",
                    "AvailabilityZone"
                ]
            },
            "Description": "AvailabilityZone of WebServer"
        },
        "SSHToWebServer": {
            "Value": {
                "Fn::Join": [
                    "",
                    [
                        "ssh -i /path/to/",
                        {
                            "Ref": "KeyName"
                        },
                        ".pem",
                        " ec2-user@",
                        {
                            "Fn::GetAtt": [
                                "WebApp",
                                "PublicIp"
                            ]
                        }
                    ]
                ]
            },
            "Description": "SSH command to connect WebServer"
        }
    }
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CloudFormationでLaravel5.5が動く環境をEC2(Ubutu18.04)上に作ったときのまとめ

GWだったので趣味で開発してるLaravelプロジェクトをEC2で動かすために必要な環境をCloudFormationで立ててみました。その時に必要となった知識をまとめておきます。

必要な環境

  • OS

    • Ubuntu18.04
  • 必要サーバ

    • EC2インスタンス1台
  • インストールが必要なもの(ざっくり)

    • php7.2
    • php-fpm
    • composer
    • Laravelの動作に必要なPHPのライブラリ群
    • nginx
  • 追加で必要なサービス

    • Elastic IP
  • Security Groupの要件

    • ssh接続の許可
    • http接続の許可

CloudFormationによるインスタンスの管理

CloudFormationには初期化コマンドを実行するための仕組みをpythonスクリプトで提供していますが、Ubuntu18.04にはデフォルトで備えられていないので自前インストールします。pipを使って下記のコマンドで実現できました。

sudo apt-get update
sudo apt-get -y install python-pip
pip install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz
sudo cp -a /usr/local/init/ubuntu/cfn-hup /etc/init.d/cfn-hup
chmod u+x /etc/init.d/cfn-hup
sudo update-rc.d cfn-hup defaults
sudo service cfn-hup start

これにより

  • テンプレート内でパッケージインストールなどをパラメータで指定して実行(cfn-init)
  • cfn-initで実行したコマンドのステータスを見て通達(cfn-signal)
  • テンプレート更新によるstack更新を検知するデーモン(cfn-hup)

が利用可能になります。他にもありますが、使ってないので触れません。

cfn-init

cfn-init ヘルパースクリプトは、AWS::CloudFormation::Init キーからテンプレートメタデータを読み取り、それに応じて様々な処理を実行します。(公式ドキュメント抜粋)
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cfn-init.html

実行コマンド例

sudo /usr/local/bin/cfn-init -v --stack "YourStackName" --resource WebApp --configsets Install --region "YourRegion"

設定の読み込み

CloudFormationの中にResources.WebApp.Metadata.AWS::CloudFormation::Initという宣言を書き、その要素として実行コマンドを記述できます。
configSetsというパラメータに実行するtaskをまとめて指定することができるので、ここに必要なtaskを登録しましょう。

"Resources": {
    "WebApp": {
        "Metadata": {
            "AWS::CloudFormation::Init": {
                "configSets": {
                    "Install": [
                        "taskName1",
                        "taskName2",
                        "..."
                    ]
                },
                "taskName1": {
                    "..."
                },
                "taskName2": {
                    "..."
                },
                "..."
            }
        }
    }    
}

taskに指定できるコマンドにはいくつか種類があるので今回用いたものを書いていきます。

公式ドキュメントはこちら
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-init.html

packageインストール

aptコマンドを使ったパッケージインストールは下記のように記述すると必要なパッケージをインストールできます。

"taskName": {
    "packages": {
        "apt": {
            "nginx": [],
            "php7.2": [],
            "php-fpm": [],
            "php7.2-mysql": [],
            "php7.2-zip": [],
            "php7.2-mbstring": [],
            "php7.2-dom": [],
            "php7.2-curl": [],
            "composer": []
        }
    }
}

ファイル作成

例えばnginxの設定ファイルを作成したければ下記のような記述をすればパーミッションを指定した上で作成が可能です。

区切り文字を改行コードで指定しているため、複数行に渡って記述することができます。

"taksName": {
     "files": {
        "/etc/nginx/nginx.conf": {
            "content": {
                "Fn::Join": [
                    "\n",
                    [
                        "your settings",
                        "write here"
                    ]
                ]
            },
            "mode": "000400",
            "owner": "root",
            "group": "root"
        }
    }
}

コマンド実行

これは自由度が高いです。好きなコマンドを実行できます。

"taskName": {
    "commands": {
        "makeConfDir": {
            "command" : "sudo mkdir -p /etc/nginx/common"
        }
    }
}

プロセス起動

services キーを使用すると、インスタンスが起動されるときに有効化または無効化する必要のあるサービスを定義できます。(公式ドキュメント抜粋)

Linuxではsysvinitキーを指定することで初回起動時の振る舞いを指定できるようです。

用いたオプションの意味は下記のとおりです。
enabled: 起動時にサービスを自動的に開始させるかどうか
ensureRunning: cfn-init が終了した後でサービスを実行するかどうか
files: 読み込む設定ファイルのリスト

"taskName": {
     "services": {
         "sysvinit": {
             "cfn-hup": {
                 "enabled": "true",
                 "ensureRunning": "true",
                 "files": [
                     "/etc/cfn/cfn-hup.conf",
                     "/etc/cfn/hooks.d/cfn-auto-reloader.conf"
                 ]
             }
         }
     }
}

ログの場所

重要な情報が入ってるのでCloudFormationを使う時はこのログファイルを見ることになると思います。

# 詳細なログ
/var/log/cfn-init.log
# 結果だけ出力されるログ
/var/log/cfn-init-cmd.log

cfn-signal

cfn-initの実行後のステータスを引数に与えて使うことで状態を追跡できるようになります。
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cfn-signal.html

ドキュメントの通り、下記のように使って、cfn-init実行後のステータス$?を渡して実行します。


"UserData": {
    "Fn::Base64": {
        "Fn::Join": [
            "",
            [
                "#!/bin/bash -x\n",
                "# Install the files and packages from the metadata\n",
                "/opt/aws/bin/cfn-init -v ",
                "         --stack ",
                {
                    "Ref": "AWS::StackName"
                },
                "         --resource MyInstance ",
                "         --region ",
                {
                    "Ref": "AWS::Region"
                },
                "\n",
                "# Signal the status from cfn-init\n",
                "/opt/aws/bin/cfn-signal -e $? ",
                "         --stack ",
                {
                    "Ref": "AWS::StackName"
                },
                "         --resource MyInstance ",
                "         --region ",
                {
                    "Ref": "AWS::Region"
                },
                "\n"
            ]
        ]
    }
}

cfn-hup

cfn-hupは2つの設定ファイルを用いて動作させます。
/etc/cfn/cfn-hup.conf: 変更の検知
/etc/cfn/hooks.d/cfn-auto-reloader.conf: hook処理の定義

/etc/cfn/cfn-hup.confのintervalは変更があったかを調べる周期なので、開発中は短くしておくと便利です(デフォルト15分)。
hookの設定ファイルにupdateされたらcfn-initを実行するように書いておきます。

"files": {
    "/etc/cfn/cfn-hup.conf": {
        "content": {
            "Fn::Join": [
                "",
                [
                    "[main]\n",
                    "stack=",
                    {
                        "Ref": "AWS::StackId"
                    },
                    "\n",
                    "region=",
                    {
                        "Ref": "AWS::Region"
                    },
                    "\n",
                    "interval=5",
                    "\n"
                ]
            ]
        },
        "mode": "000400",
        "owner": "root",
        "group": "root"
    },
    "/etc/cfn/hooks.d/cfn-auto-reloader.conf": {
        "content": {
            "Fn::Join": [
                "",
                [
                    "[cfn-auto-reloader-hook]\n",
                    "triggers=post.update\n",
                    "path=Resources.WebApp.Metadata.AWS::CloudFormation::Init\n",
                    "action=/usr/local/bin/cfn-init -v ",
                    "         --stack ",
                    {
                        "Ref": "AWS::StackName"
                    },
                    "         --resource WebApp ",
                    "         --configsets Install ",
                    "         --region ",
                    {
                        "Ref": "AWS::Region"
                    },
                    "\n",
                    "runas=root\n"
                ]
            ]
        },
        "mode": "000400",
        "owner": "root",
        "group": "root"
    }
}

設定ファイルのサンプル

Laravelはcomposerを使っており、設定ファイルはjson形式なのでCloudFormationの設定ファイルもjsonに合わせています。
本当はコメント使えないですが、便宜的に追加してます。

SecurityGroupやElastic IPについては特に困ったことは無かったので説明しませんでしたが、このサンプルに含まれています。

{
   "Resources": {
        # ssh接続するための設定
        "SSHGroup": {
            "Type": "AWS::EC2::SecurityGroup",
            "Properties": {
                "GroupDescription": "Enable SSH access via port 22",
                "SecurityGroupIngress": [
                    {
                        "IpProtocol": "tcp",
                        "CidrIp": "0.0.0.0/0",
                        "FromPort": "22",
                        "ToPort": "22"
                    }
                ]
            }
        },
        # httpとhttps通信を許可する設定
        "httpGroup": {
            "Type": "AWS::EC2::SecurityGroup",
            "Properties": {
                "GroupDescription": "Enable http access via port 80",
                "SecurityGroupIngress": [
                    {
                        "IpProtocol": "tcp",
                        "CidrIp": "0.0.0.0/0",
                        "FromPort": "80",
                        "ToPort": "80"
                    }
                ]
            }
        }, 
        # IPアドレスを固定するために割り当てる
        "WebServerEip": {
            "Type": "AWS::EC2::EIP",
            "Properties": {
                "InstanceId": {
                    "Ref": "WebApp"
                }
            }
        },
        # 立ち上げるEC2インスタンスの設定
        "WebApp": {
            "Type": "AWS::EC2::Instance",
            "Metadata": {
                "AWS::CloudFormation::Init": {
                    "configSets": {
                        "Install": [
                            "Install",
                            "SetupNginx",
                            "StartNginx"
                        ]
                    },
                    "Install": {
                        # 必要なパッケージのインストール
                        "packages": {
                            "apt": {
                                "nginx": [],
                                "php7.2": [],
                                "php-fpm": [],
                                "php7.2-mysql": [],
                                "php7.2-zip": [],
                                "php7.2-mbstring": [],
                                "php7.2-dom": [],
                                "php7.2-curl": [],
                                "composer": []
                            }
                        },
                        # 初期化時に実行するコマンド
                        "files": {
                            "/etc/cfn/cfn-hup.conf": {
                                "content": {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "[main]\n",
                                            "stack=",
                                            {
                                                "Ref": "AWS::StackId"
                                            },
                                            "\n",
                                            "region=",
                                            {
                                                "Ref": "AWS::Region"
                                            },
                                            "\n",
                                            # 開発中はチェック頻度短くしたほうが楽(デフォルト15分)
                                            "interval=5",
                                            "\n"
                                        ]
                                    ]
                                },
                                "mode": "000400",
                                "owner": "root",
                                "group": "root"
                            },
                            # stackを更新した時に反映させるためのデーモンの設定
                            "/etc/cfn/hooks.d/cfn-auto-reloader.conf": {
                                "content": {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "[cfn-auto-reloader-hook]\n",
                                            "triggers=post.update\n",
                                            "path=Resources.WebApp.Metadata.AWS::CloudFormation::Init\n",
                                            "action=/usr/local/bin/cfn-init -v ",
                                            "         --stack ",
                                            {
                                                "Ref": "AWS::StackName"
                                            },
                                            "         --resource WebApp ",
                                            "         --configsets Install ",
                                            "         --region ",
                                            {
                                                "Ref": "AWS::Region"
                                            },
                                            "\n",
                                            "runas=root\n"
                                        ]
                                    ]
                                },
                                "mode": "000400",
                                "owner": "root",
                                "group": "root"
                            }
                        },
                        # cfn-hupを初期起動させる
                        "services": {
                            "sysvinit": {
                                "cfn-hup": {
                                    "enabled": "true",
                                    "ensureRunning": "true",
                                    "files": [
                                        "/etc/cfn/cfn-hup.conf",
                                        "/etc/cfn/hooks.d/cfn-auto-reloader.conf"
                                    ]
                                }
                            }
                        }
                    },
                    # nginxの設定に必要なファイルやディレクトリを作成
                    "SetupNginx": {
                        # ここで作ったディレクトリはnginxの設定ファイルでincludeする必要がある
                        "commands": {
                            "makeConfDir": {
                                "command" : "sudo mkdir -p /etc/nginx/common"
                            }
                        },
                        "files": {
                            "/etc/nginx/nginx.conf": {
                                "content": {
                                    "Fn::Join": [
                                        "\n",
                                        [
                                            "your settings"
                                        ]
                                    ]
                                },
                                "mode": "000400",
                                "owner": "root",
                                "group": "root"
                            },
                            # サービス毎に分けて管理する
                            "/etc/nginx/sites-available/your_site.conf": {
                                "content": {
                                    "Fn::Join": [
                                        "\n",
                                        [
                                            "your_settings"
                                        ]
                                    ]
                                },
                                "mode": "000400",
                                "owner": "root",
                                "group": "root"
                            },
                            # php-fpmの設定ファイルを分けておく
                            "/etc/nginx/common/php_fastcgi.conf": {
                                "content": {
                                    "Fn::Join": [
                                        "\n",
                                        [
                                            "your_settings"
                                        ]
                                    ]
                                },
                                "mode": "000400",
                                "owner": "root",
                                "group": "root"
                            },
                            "/etc/nginx/common/general.conf": {
                                "content": {
                                    "Fn::Join": [
                                        "\n",
                                        [
                                            "your settings"
                                        ]
                                    ]
                                },
                                "mode": "000400",
                                "owner": "root",
                                "group": "root"
                            }
                        }
                    },
                    # 起動
                    "StartNginx": {
                        "commands" : {
                            "start": {
                                "command" : "sudo systemctl start nginx"
                            }
                        }
                    }
                }
            },
            "Properties": {
                # Ubuntu18.04のami
                "ImageId": "ami-0eb48a19a8d81e20b",
                "InstanceType": {
                    "Ref": "InstanceType"
                },
                "KeyName": {
                    "Ref": "KeyName"
                },
                "SecurityGroupIds": [
                    {
                        "Ref": "SSHGroup"
                    },
                    {
                        "Ref": "httpGroup"
                    }
                ],
          # 最初に実行するコマンドの指定
                "UserData": {
                    "Fn::Base64": {
                        "Fn::Join": [
                            "",
                            [
                                "#!/bin/bash -xe\n",
                                "sudo apt-get update\n",
                                "sudo apt-get -y install python-pip\n",
                                # cfn-hupが使えるようにする
                                "pip install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n",
                                "sudo cp -a /usr/local/init/ubuntu/cfn-hup /etc/init.d/cfn-hup\n",
                                "chmod u+x /etc/init.d/cfn-hup\n",
                                "sudo update-rc.d cfn-hup defaults\n",
                                "sudo service cfn-hup start\n",
                                "# Install the files and packages from the metadata\n",
                                "sudo /usr/local/bin/cfn-init -v ",
                                "         --stack ",
                                {
                                    "Ref": "AWS::StackName"
                                },
                                "         --resource WebApp ",
                                "         --configsets Install ",
                                "         --region ",
                                {
                                    "Ref": "AWS::Region"
                                },
                                "\n",
                                # エラーハンドリング用
                                "# Signal the status from cfn-init\n",
                                "sudo /usr/local/bin/cfn-signal -e $? ",
                                "         --stack ",
                                {
                                    "Ref": "AWS::StackName"
                                },
                                "         --resource WebApp ",
                                "         --region ",
                                {
                                    "Ref": "AWS::Region"
                                },
                                "\n"
                            ]
                        ]
                    }
                }
            }
        }
    },
    # stack作成時にオプション選択するパラメータを指定
    "Parameters": {
        "KeyName": {
            "Description": "Name of an existing EC2 KeyPair to enable SSH access to the web server",
            "Type": "String",
            "Default": "your_key"
        },
        "InstanceType": {
            "Description": "WebServer EC2 instance type",
            "Type": "String",
            "Default": "t2.micro",
            "AllowedValues": [
                "t1.micro",
                "t2.nano",
                "t2.micro"
            ],
            "ConstraintDescription": "must be a valid EC2 instance type."
        }
    },
    # stackの状態を見た時に表示される内容
    "Outputs": {
        "WebServerIpAddress": {
            "Value": {
                "Fn::GetAtt": [
                    "WebApp",
                    "PublicIp"
                ]
            },
            "Description": "IP Address of WebServer"
        },
        "WebServerAvailabilityZone": {
            "Value": {
                "Fn::GetAtt": [
                    "WebApp",
                    "AvailabilityZone"
                ]
            },
            "Description": "AvailabilityZone of WebServer"
        },
        "SSHToWebServer": {
            "Value": {
                "Fn::Join": [
                    "",
                    [
                        "ssh -i /path/to/",
                        {
                            "Ref": "KeyName"
                        },
                        ".pem",
                        " ec2-user@",
                        {
                            "Fn::GetAtt": [
                                "WebApp",
                                "PublicIp"
                            ]
                        }
                    ]
                ]
            },
            "Description": "SSH command to connect WebServer"
        }
    }
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PHP Warning: require(/path/to/vendor/composer/../symfony/polyfill-mbstring/bootstrap.php): failed to open stream: No such file or directory in /path/to/vendor/composer/autoload_real.php on line 66となったときの対応方法

  • 環境
    • macOS Mojave バージョン10.14.4
    • PHP 7.3.1 (cli)
    • Composer version 1.8.0

事象 : Laravelのバージョンを確認しようとしたら怒られた。

$ php artisan -V
PHP Warning:  require(/path/to/vendor/composer/../symfony/polyfill-mbstring/bootstrap.php): failed to open stream: No such file or directory in /path/to/vendor/composer/autoload_real.php on line 66

Warning: require(/path/to/vendor/composer/../symfony/polyfill-mbstring/bootstrap.php): failed to open stream: No such file or directory in /path/to/vendor/composer/autoload_real.php on line 66
PHP Fatal error:  require(): Failed opening required '/path/to/vendor/composer/../symfony/polyfill-mbstring/bootstrap.php' (include_path='.:/usr/local/Cellar/php/7.3.1/share/php/pear') in /path/to/vendor/composer/autoload_real.php on line 66

Fatal error: require(): Failed opening required '/path/to/vendor/composer/../symfony/polyfill-mbstring/bootstrap.php' (include_path='.:/usr/local/Cellar/php/7.3.1/share/php/pear') in /path/to/vendor/composer/autoload_real.php on line 66

原因 : 必要なファイルがvenderディレクトリにないから

symfony - laravel on cpanel raise error for autoload_real.php on line 66 - Stack Overflow

対応 : composer updateする

$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 77 installs, 4 updates, 0 removals
  - Installing sebastian/resource-operations (2.0.1): Loading from cache
  - Installing sebastian/object-reflector (1.1.1): Loading from cache
  - Installing sebastian/recursion-context (3.0.0): Loading from cache
  - Installing sebastian/object-enumerator (3.0.3): Loading from cache
  - Installing sebastian/exporter (3.1.0): Loading from cache
  - Installing sebastian/environment (4.2.2): Downloading (100%)         
  - Installing sebastian/diff (3.0.2): Loading from cache
  - Installing sebastian/comparator (3.0.2): Loading from cache
  - Installing phpunit/php-timer (2.1.1): Loading from cache
  - Installing phpunit/php-file-iterator (2.0.2): Loading from cache
  - Updating theseer/tokenizer (1.1.0 => 1.1.2): Loading from cache
  - Installing sebastian/code-unit-reverse-lookup (1.0.1): Loading from cache
  - Installing phpunit/php-token-stream (3.0.1): Loading from cache
  - Installing phpunit/php-code-coverage (6.1.4): Loading from cache
  - Installing doctrine/instantiator (1.2.0): Loading from cache
  - Updating symfony/polyfill-ctype (v1.10.0 => v1.11.0): Loading from cache
  - Updating phpdocumentor/reflection-docblock (4.3.0 => 4.3.1): Downloading (100%)         
  - Installing phpspec/prophecy (1.8.0): Loading from cache
  - Installing phar-io/manifest (1.0.3): Loading from cache
  - Installing myclabs/deep-copy (1.9.1): Loading from cache
  - Updating phpunit/phpunit (7.5.6 => 7.5.9): Loading from cache
  - Installing vlucas/phpdotenv (v2.6.1): Loading from cache
  - Installing symfony/css-selector (v4.2.8): Loading from cache
  - Installing tijsverkoyen/css-to-inline-styles (2.2.1): Loading from cache
  - Installing symfony/polyfill-php72 (v1.11.0): Loading from cache
  - Installing symfony/polyfill-mbstring (v1.11.0): Loading from cache
  - Installing symfony/var-dumper (v4.2.8): Downloading (100%)         
  - Installing symfony/routing (v4.2.8): Downloading (100%)         
  - Installing symfony/process (v4.2.8): Loading from cache
  - Installing psr/log (1.1.0): Loading from cache
  - Installing symfony/debug (v4.2.8): Loading from cache
  - Installing symfony/http-foundation (v4.2.8): Downloading (100%)         
  - Installing symfony/polyfill-intl-idn (v1.11.0): Loading from cache
  - Installing symfony/contracts (v1.0.2): Loading from cache
  - Installing symfony/event-dispatcher (v4.2.8): Loading from cache
  - Installing symfony/http-kernel (v4.2.8): Downloading (100%)         
  - Installing symfony/finder (v4.2.8): Loading from cache
  - Installing symfony/console (v4.2.8): Loading from cache
  - Installing symfony/polyfill-iconv (v1.11.0): Loading from cache
  - Installing doctrine/lexer (v1.0.1): Loading from cache
  - Installing egulias/email-validator (2.1.7): Loading from cache
  - Installing swiftmailer/swiftmailer (v6.2.1): Loading from cache
  - Installing paragonie/random_compat (v9.99.99): Loading from cache
  - Installing ramsey/uuid (3.8.0): Loading from cache
  - Installing psr/simple-cache (1.0.1): Loading from cache
  - Installing psr/container (1.0.0): Loading from cache
  - Installing opis/closure (3.2.0): Downloading (100%)         
  - Installing symfony/translation (v4.2.8): Downloading (100%)         
  - Installing nesbot/carbon (1.37.1): Downloading (100%)         
  - Installing monolog/monolog (1.24.0): Loading from cache
  - Installing league/flysystem (1.0.51): Loading from cache
  - Installing erusev/parsedown (1.7.3): Loading from cache
  - Installing dragonmantank/cron-expression (v2.3.0): Loading from cache
  - Installing nikic/php-parser (v4.2.1): Loading from cache
  - Installing doctrine/inflector (v1.3.0): Loading from cache
  - Installing ralouphie/getallheaders (2.0.5): Loading from cache
  - Installing psr/http-message (1.0.1): Loading from cache
  - Installing guzzlehttp/psr7 (1.5.2): Loading from cache
  - Installing guzzlehttp/promises (v1.3.1): Loading from cache
  - Installing guzzlehttp/guzzle (6.3.3): Loading from cache
  - Installing laravel/slack-notification-channel (v1.0.3): Loading from cache
  - Installing laravel/framework (v5.7.28): Downloading (100%)         
  - Installing lcobucci/jwt (3.2.5): Loading from cache
  - Installing php-http/promise (v1.0.0): Loading from cache
  - Installing php-http/httplug (v1.1.0): Loading from cache
  - Installing php-http/guzzle6-adapter (v1.1.1): Loading from cache
  - Installing zendframework/zend-diactoros (1.8.6): Loading from cache
  - Installing nexmo/client (1.7.0): Downloading (100%)         
  - Installing laravel/nexmo-notification-channel (v1.0.1): Loading from cache
  - Installing fideloper/proxy (4.1.0): Loading from cache
  - Installing jakub-onderka/php-console-color (v0.2): Loading from cache
  - Installing jakub-onderka/php-console-highlighter (v0.4): Loading from cache
  - Installing dnoegel/php-xdg-base-dir (0.1): Loading from cache
  - Installing psy/psysh (v0.9.9): Loading from cache
  - Installing laravel/tinker (v1.0.8): Loading from cache
  - Installing beyondcode/laravel-dump-server (1.2.2): Loading from cache
  - Installing fzaninotto/faker (v1.8.0): Loading from cache
  - Installing hamcrest/hamcrest-php (v2.0.0): Loading from cache
  - Installing mockery/mockery (1.2.2): Loading from cache
  - Installing filp/whoops (2.3.1): Loading from cache
  - Installing nunomaduro/collision (v2.1.1): Loading from cache
phpunit/php-code-coverage suggests installing ext-xdebug (^2.6.0)
symfony/routing suggests installing symfony/config (For using the all-in-one router or any loader)
symfony/routing suggests installing symfony/yaml (For using the YAML loader)
symfony/routing suggests installing symfony/expression-language (For using expression matching)
symfony/routing suggests installing doctrine/annotations (For using the annotation loader)
symfony/contracts suggests installing psr/cache (When using the Cache contracts)
symfony/contracts suggests installing symfony/cache-contracts-implementation
symfony/contracts suggests installing symfony/service-contracts-implementation
symfony/event-dispatcher suggests installing symfony/dependency-injection
symfony/http-kernel suggests installing symfony/browser-kit
symfony/http-kernel suggests installing symfony/config
symfony/http-kernel suggests installing symfony/dependency-injection
symfony/console suggests installing symfony/lock
swiftmailer/swiftmailer suggests installing true/punycode (Needed to support internationalized email addresses, if ext-intl is not installed)
paragonie/random_compat suggests installing ext-libsodium (Provides a modern crypto API that can be used to generate random bytes.)
ramsey/uuid suggests installing ircmaxell/random-lib (Provides RandomLib for use with the RandomLibAdapter)
ramsey/uuid suggests installing ext-libsodium (Provides the PECL libsodium extension for use with the SodiumRandomGenerator)
ramsey/uuid suggests installing ext-uuid (Provides the PECL UUID extension for use with the PeclUuidTimeGenerator and PeclUuidRandomGenerator)
ramsey/uuid suggests installing moontoast/math (Provides support for converting UUID to 128-bit integer (in string form).)
ramsey/uuid suggests installing ramsey/uuid-doctrine (Allows the use of Ramsey\Uuid\Uuid as Doctrine field type.)
ramsey/uuid suggests installing ramsey/uuid-console (A console application for generating UUIDs with ramsey/uuid)
symfony/translation suggests installing symfony/config
symfony/translation suggests installing symfony/yaml
nesbot/carbon suggests installing friendsofphp/php-cs-fixer (Needed for the `composer phpcs` command. Allow to automatically fix code style.)
nesbot/carbon suggests installing phpstan/phpstan (Needed for the `composer phpstan` command. Allow to detect potential errors.)
monolog/monolog suggests installing graylog2/gelf-php (Allow sending log messages to a GrayLog2 server)
monolog/monolog suggests installing sentry/sentry (Allow sending log messages to a Sentry server)
monolog/monolog suggests installing doctrine/couchdb (Allow sending log messages to a CouchDB server)
monolog/monolog suggests installing ruflin/elastica (Allow sending log messages to an Elastic Search server)
monolog/monolog suggests installing php-amqplib/php-amqplib (Allow sending log messages to an AMQP server using php-amqplib)
monolog/monolog suggests installing ext-amqp (Allow sending log messages to an AMQP server (1.0+ required))
monolog/monolog suggests installing ext-mongo (Allow sending log messages to a MongoDB server)
monolog/monolog suggests installing mongodb/mongodb (Allow sending log messages to a MongoDB server via PHP Driver)
monolog/monolog suggests installing aws/aws-sdk-php (Allow sending log messages to AWS services like DynamoDB)
monolog/monolog suggests installing rollbar/rollbar (Allow sending log messages to Rollbar)
monolog/monolog suggests installing php-console/php-console (Allow sending log messages to Google Chrome)
league/flysystem suggests installing league/flysystem-eventable-filesystem (Allows you to use EventableFilesystem)
league/flysystem suggests installing league/flysystem-rackspace (Allows you to use Rackspace Cloud Files)
league/flysystem suggests installing league/flysystem-azure (Allows you to use Windows Azure Blob storage)
league/flysystem suggests installing league/flysystem-webdav (Allows you to use WebDAV storage)
league/flysystem suggests installing league/flysystem-aws-s3-v2 (Allows you to use S3 storage with AWS SDK v2)
league/flysystem suggests installing league/flysystem-aws-s3-v3 (Allows you to use S3 storage with AWS SDK v3)
league/flysystem suggests installing spatie/flysystem-dropbox (Allows you to use Dropbox storage)
league/flysystem suggests installing srmklive/flysystem-dropbox-v2 (Allows you to use Dropbox storage for PHP 5 applications)
league/flysystem suggests installing league/flysystem-cached-adapter (Flysystem adapter decorator for metadata caching)
league/flysystem suggests installing league/flysystem-sftp (Allows you to use SFTP server storage via phpseclib)
league/flysystem suggests installing league/flysystem-ziparchive (Allows you to use ZipArchive adapter)
laravel/framework suggests installing aws/aws-sdk-php (Required to use the SQS queue driver and SES mail driver (^3.0).)
laravel/framework suggests installing doctrine/dbal (Required to rename columns and drop SQLite columns (^2.6).)
laravel/framework suggests installing league/flysystem-aws-s3-v3 (Required to use the Flysystem S3 driver (^1.0).)
laravel/framework suggests installing league/flysystem-cached-adapter (Required to use the Flysystem cache (^1.0).)
laravel/framework suggests installing league/flysystem-rackspace (Required to use the Flysystem Rackspace driver (^1.0).)
laravel/framework suggests installing league/flysystem-sftp (Required to use the Flysystem SFTP driver (^1.0).)
laravel/framework suggests installing moontoast/math (Required to use ordered UUIDs (^1.1).)
laravel/framework suggests installing pda/pheanstalk (Required to use the beanstalk queue driver (^3.0|^4.0).)
laravel/framework suggests installing predis/predis (Required to use the redis cache and queue drivers (^1.0).)
laravel/framework suggests installing pusher/pusher-php-server (Required to use the Pusher broadcast driver (^3.0).)
laravel/framework suggests installing symfony/dom-crawler (Required to use most of the crawler integration testing tools (^4.1).)
laravel/framework suggests installing symfony/psr-http-message-bridge (Required to psr7 bridging features (^1.0).)
lcobucci/jwt suggests installing mdanter/ecc (Required to use Elliptic Curves based algorithms.)
psy/psysh suggests installing ext-pdo-sqlite (The doc command requires SQLite to work.)
psy/psysh suggests installing hoa/console (A pure PHP readline implementation. You'll want this if your PHP install doesn't already support readline or libedit.)
filp/whoops suggests installing whoops/soap (Formats errors as SOAP responses)
Writing lock file
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
Discovered Package: beyondcode/laravel-dump-server
Discovered Package: fideloper/proxy
Discovered Package: laravel/nexmo-notification-channel
Discovered Package: laravel/slack-notification-channel
Discovered Package: laravel/tinker
Discovered Package: nesbot/carbon
Discovered Package: nunomaduro/collision
Package manifest generated successfully.

# 治りました。
$ php artisan -V
Laravel Framework 5.7.28

この間は問題なかったのに・・・なぜ?

ちょっと前の結果
$ php artisan -V
Laravel Framework 5.8.14

何かが更新でもされたのだろうか?それともなにかやったのを忘却しているのだろうか?

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【PHP】【Laravel】League of Legendsの公式からAPIキーを取得する。

きっかけ

プログラミングを学ぶことも楽しいが、ゲームもやはり楽しい。(特にlol)
最近プラチナに昇格して、ほくほくである。
プログラミングもようやく色々とできるようになったので、いっちょここらで自作のwebサイトを作ろうかと意気込んでいた。

そうだlolのデータを取得して分析サイト(個人趣味)を作ろう!

思い立ったが吉日。早速設計することにした。(頭の中で)
lolというゲームにおいて、忘れてはならないのが、OP.GGというサイトである。
このサイトで自分のゲームの中の名前を入れるやいなやものすごい量の戦績データなどを振り返ることのできる
神サイトである。
また、チャンピオンの勝率や、そのチャンピオンの使用武器ごとの勝率などとにかくすごい。
僕自身かなりお世話になったサイトである。僕をあおってきたやつの名前を検索してランクをあざ笑ったりした

なので、最初はそのサイトをスクレイピングして~(いいのかわからんが)と考えていたのだが、検索したところ。。。

Riotから既にAPIが公開されているではないかあああああ!!!!

まさにS8途中にADCがADCでないメタが流行ったばりに衝撃を受けた。
lolネタがわかるひとならきっと伝わっていると思う。

参考

Riot Games APIでLeague of Legendsの試合データを取得しよう
RiotAPIを使ってLP変動を調べてみる

公式サイト

幸運にも偉大なる先人たちがやってくださっていた。ありがとうございます。ちょっと記事が古いけども

実践

今回の流れとしては、公式から発行されているAPIキーを使って自身に紐づくサモナーIDを取得して画面に表示しちゃおうというもの
まずはrouteから

route

image.png

シンプルなルーティング。indexControllerのgetIDapiメソッドを使う。

controller

image.png

変数api_keyには、公式から発行されるAPIキーを入力する。
変数summoner_nameには、自分のサモナーネームを入れる。
変数regionには、自分のやっているサーバーを入れる。日本ならjp、NAならna

上記の変数は別に作成せずとも変数urlの中にべた書きで問題ない。変数urlさえ正しく作れていればOK

その後は、curlを使ってサーバーへリクエストを送り、サモナーIDを手に入れるという形。
この辺は参考サイト2番目のほうで詳しくやっていただいている。

セッションの項目は僕が勝手に作ってるだけなので気にしないでください。

取得し終えたら、api.blade.phpへ変数resultを返す。
この変数resultは配列になっているので注意。

view

image.png

自分好みでわんわんおやらふざけているが最悪、11行目がかけていれば大丈夫。
ボタンの部分は今後自分が作る予定のために書いているので気にしないでください。
ソースがふざけすぎててわらった

実行結果

image.png

なんかこんな感じでidやらサモナーレベルやら出たら合格!
nameには自分のサモナーネームが入っているよ。
(一応怖いので一部マスクしました。)

注意点

ハマってしまった箇所が一点だけ。。。
参考サイトをみていてずっとうまくいかなかったのですが、Controllerのurlには注意してください。

https://jp1.api.riotgames.com/lol/summoner/v4/summoners/by-name/summoner_name.?api_key=[key]

この部分が参考サイトだと古いので必ず公式サイトを参照してください。(当時クローズドベータだったからだと予想)

あとがき

僕自身APIを利用すること自体が初めてなので、HTTPリクエストとかも完全に理解してないと思います。。。(勉強します)
なので、文章自体が少しおかしかったり、なんならviewはたぶんインデントとかひどいと思うので
もしそういうことがあればコメントいただけたらと思います。。。

champion.gg?そんなサイトはもう知らんなぁ!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む