GCPでLaravelのログをStackDriverに出力するには
TL;DR
-
monolog-stackdriver
を使うことで、LaravelログをstackDriverで表示できる - envファイルの設定で、ログの出力先を通常ログ or StackDriverの切り替え可能
- インタンスを設定しないと、StackDriverの グローバル カテゴリに出力される
- GCEの
instance_id
を指定することで、コンピュータに紐付けた出力もできるがid取得方法までは調べていない
ログ送信手順
composerでパッケージ導入
こちらのパッケージを使います。
https://packagist.org/packages/codeinternetapplications/monolog-stackdriver
composer require codeinternetapplications/monolog-stackdriver
ログの送信先を設定する
1.ENVファイルの設定
2.config/logging.php設定
config/logging.phpはStackDriverでの表示先で設定量が異なります
- グローバル ->共通の設定を行うだけ
- インタンス名単位(今回はGCE) ->インスタンス名のみ設定
- インスタンス(マシーン)単位 ->インスタンIDも設定
ENVファイルを設定する
ログを表示したいレベルに合わせて、envを記載します。
# 必須
LOG_CHANNEL=stackdriver
# インスタンス名別のログ保存する場合
GCP_LOG_RESOURCE_NAME=hoge_resource
# インスタンス(マシーン)単位のログ保存する場合
GCP_LOG_INSTANCE_ID=hoge_xxxxxx
GCP_LOG_PROJECT_ID=hoge_id
GCP_LOG_ZONE=hoge_zone
hoge_
の値は適切な値に変更してください。
config/logging.phpを設定する
グローバルで表示されるように設定する場合
'channels' => [
// ( ... )
'stackdriver' => [
'driver' => 'custom',
'via' => CodeInternetApplications\MonologStackdriver\Laravel\CreateStackdriverLogger::class,
'logName' => env('APP_NAME', 'my-project-log'),
//GCP内部からの保存には必要ない
// 'loggingClientOptions' => [
// 'keyFilePath' => '/path/to/service-account-key-file.json',
// ],
// 'loggerOptions' => [],
// 'lineFormat' => '%message%',
// 'entryOptionsWrapper' => 'stackdriver',
],
]
logName
項目は適切な名前をつけてください
loggingClientOptions
項目で、jsonのキーファイルを指定しますが、GCP内部でのログ送信にjsonは必要ありません。
他のクラウド(AWSなど)から送信する場合に指定します。
ログ表示例
良い点
- 設定が簡単
- 多くの場合で適用できる
- 複数のインスタンのプログラムからのログを集約できる
悪い点
- 複数のマシーンからのログを識別する工夫が別途必要
-エラー調査の際、グローバルとマシンログを往復して比較する必要がある
インスタンス名別で表示されるように設定する場合
'channels' => [
// ( ... )
'stackdriver' => [
'driver' => 'custom',
'via' => CodeInternetApplications\MonologStackdriver\Laravel\CreateStackdriverLogger::class,
'logName' => env('APP_NAME', 'my-project-log'),
'loggerOptions' => [
'labels' => [
'compute.googleapis.com/resource_name' => env('GCP_LOG_RESOURCE_NAME', 'dev-web-instance'),
],
'resource' => [
'type' => 'gce_instance',
],
]
//GCP内部からの保存には必要ない
// 'loggingClientOptions' => [
// 'keyFilePath' => '/path/to/service-account-key-file.json',
// ],
// 'loggerOptions' => [],
// 'lineFormat' => '%message%',
// 'entryOptionsWrapper' => 'stackdriver',
],
]
グローバル設定に、 loggerOptions
を追加しています。
ここでは、GCEのログなのでインスタンにGCEを指定しています。
指定したい箇所のログで実際に指定されている項目を設定ファイルにコピーすれば、その箇所に入るようになります。
ログ表示例
良い点
- サーバと同じカテゴリなので、時間軸に沿った把握ができる
- マシーンをグループ化していなければ、マシーン名とログが一致する
- オートスケールマシーンでもグループに集約される形で取得できる
悪い点
- マシーンの識別はできない
- instance_idが空でも表示できているが、正常なログの仕様として問題ないか不明(なんらかのログサービスと連携した時の挙動が心配)
インスタンス(マシーン)単位で表示されるように設定する場合
'channels' => [
// ( ... )
'stackdriver' => [
'driver' => 'custom',
'via' => CodeInternetApplications\MonologStackdriver\Laravel\CreateStackdriverLogger::class,
'logName' => env('APP_NAME', 'my-project-log'),
'loggerOptions' => [
'labels' => [
'compute.googleapis.com/resource_name' => env('GCP_LOG_RESOURCE_NAME', 'dev-web-instance'),
],
'resource' => [
'type' => 'gce_instance',
'labels' => [
'instance_id' => env('GCP_LOG_INSTANCE_ID'),
'project_id' => env('GCP_LOG_PROJECT_ID'),
'zone' => env('GCP_LOG_ZONE'),
]
],
]
//GCP内部からの保存には必要ない
// 'loggingClientOptions' => [
// 'keyFilePath' => '/path/to/service-account-key-file.json',
// ],
// 'loggerOptions' => [],
// 'lineFormat' => '%message%',
// 'entryOptionsWrapper' => 'stackdriver',
],
]
インスタンス名別の設定に、 loggerOptions.resource.labels
を追加しています。
instance_idは、Compute Engineの詳細ページ
project_idは、TOPページに記載されています
ログ表示例
(省略)
良い点
- サーバの情報と同じ場所に格納されるので時間軸に沿った把握が簡単
- マシーンの識別もできる
悪い点 - オートスケールでidが変わる場合の対応を考える必要がある
ログ送信
Laravelの標準的なコードで送信が行える
//infoレベルログ
Log::info('InfoLogInfoTest', ['logItem1' => 'メッセージはあとから分かりやすいものを', 'logItem2' => ['ItemSub1' => '配列形式で自由にデータを入れられる', 'ItemSub2' => '入れ子も問題なし'] ]);
// errorレベルログ
Log::error('InfoLogErrorTest', ['logItem1' => 'エラーもStackDriverで正しく識別', 'logItem2' => ['ItemSub1' => '配列形式で自由にデータを入れられる', 'ItemSub2' => '入れ子も問題なし'] ]);
第1引数は、 message
に格納される
第2引数は、 jsonPayload
に格納される
StackDriverにログレベルも認識されているので、 Error
の絞り込みも行える
以上です。