はじめに
前回の AWS Lambda のCustom RuntimeでPHP用のLayer作成 で作成したLayerを使用します。
(Stackery社のlayerでも問題ないです。)
作業環境
LayerのZip作成にdockerを、AWSへのアップロードにaws-cliを使います。
- pyenv
- 1.2.9-2
- pip
- 9.0.3(python3.6.5)
- aws-cli
- 1.16.96(python3.6.5)
- sam
- 0.14.2
- 0.14.2
作業はMacOSです。
各種インストールは割愛します。
使用ソースコード
ログ出力について
AWS LambdaでPHPを使用した際の挙動として、ログ出力が不便という点があります。
API Gatewayを使用する場合はブラウザ上にvar_dump()
で表示すれば良いですが、データとして残すためにもCloudwatch logsへ出来る限り可視性が高い状態で出力しておくことが望まれます。
最近はcloudwatch logsの機能で、json形式のログから検索も可能になっているようなので、ログ出力はちゃんとしようと思う毎日です。
さて、今回はprintf
とvar_dump
とerror_log
の挙動の違い、現時点でのPHPでのログ出力方法のベストプラクティスをまとめておきます。
テストコード
<?php
function print_log(){
$temp_array = [
'hoge' => "foo",
'var' => 2,
];
printf("Hello World!\nhogehoge");
printf($temp_array);
}
function var_dump_log(){
$temp_array = [
'hoge' => "foo",
'var' => 2,
];
var_dump("Hello World!\nhogehoge");
var_dump($temp_array);
}
function error_log_log(){
$temp_array = [
'hoge' => "foo",
'var' => 2,
];
error_log("Hello World!\nhogehoge");
$json_temp_array = json_encode($temp_array);
error_log($json_temp_array);
}
function main(){
print_log();
var_dump_log();
error_log_log();
}
結果
error_log()
とjson_encode
の組み合わせが最適です。
printf
Lambda上のログ詳細: "Hello World!\nhogehogeArray"
CloudWatch logs: Hello World!
<行切り替え>hogehogeArray
printfで表示は可能ですが、複数のログを出力した際に、
1行にまとめて表示される問題があります。
\n
がCloudwatch logsでの行切り替えになっているため、想定通りの出力にならないことがありそうです。
var_dump
Lambda上のログ詳細: "string(21) \"Hello World!\nhogehoge\"\narray(2) {\n [\"hoge\"]=>\n string(3) \"foo\"\n [\"var\"]=>\n int(2)\n}\n"
CloudWatch logs: string(21) "Hello World!
<行切り替え>hogehoge"
<行切り替え>array(2) {
<行切り替え>["hoge"]=>
<行切り替え>string(3) "foo"
<行切り替え>["var"]=>
<行切り替え>int(2)
<行切り替え>}
実際に出力してみるとわかりますが、とてもログを参考にできたものはないです。ブラウザ上に表示する場合はvar_dump()がいいと思いますが、ログ出力には向いていないのがわかると思います。
error_log
error_logにArrayを入れるとwarningが出るため、先にjson_encodeしておきます。()
```
Lambda上のログ詳細: ""
CloudWatch logs: Hello World!
<行切り替え>hogehoge
<行切り替え>
{
"hoge": "foo",
"var": 2
}
```
printf, var_dumpと比べて、行切り替えのタイミングが大分よくなりました。
ただ、\nは行切り替えしたくないので、以下のラッパー関数を作成します。
function logging ($output) {
$log = "";
if(is_array($output)){
$log = json_encode($output);
$log = str_replace("\n", "\\n", $log);
} else {
$log = str_replace("\n", "\r", $log);
}
error_log($log);
}
結果
Lambda上のログ詳細: ""
CloudWatch logs: Hello World!
hogehoge
<行切り替え>
{
"hoge": "foo",
"var": 2
}
いいですね!Lambda上のログ詳細に出したい場合(デバッグ時)は、
var_dumpを使用すればいいと思います。
まとめ
PHPのログ出力について、ログ関数を入れてまで本格的にやりたくないので、手軽にできる方法を探しました。
今のところ、error_logのラッパー関数が使い心地がいいですが、よりオススメの方法があれば知りたいです。