はじめに
本記事はGoogle Cloud Platformの公式ページで公開されている「Google App Engine Articles」の紹介記事となります。今回はその中から「Using Cloud Logging in App Engine Apps」の記事を説明します。
※前回は「GAEのスケーリング 前編」(後編も後ほどリリースします。)について解説しました。今回は記事解説の第2弾となります。
Cloud Loggingとは
Cloud LoggingとはGoogle Cloud Platform(以下GCP)上で動作するアプリケーション(GAE、Managed VMs)のログを管理するための機能です。例えば、言語毎(Python/Java/PHP,Go)に提供されるAPIを利用して任意のログを出力したり、Web Console上からログの閲覧・フィルタリングをおこなったりすることができます。
ログビューワーの利用方法
開発者はGoogleが提供するDeveloper Consoleを利用してログの閲覧・フィルタリングをおこなうことができます。まずは、以下の手順からログビューワー画面を確認してみましょう。
1. Developers Consoleにアクセス
https://console.developers.google.com/project
2. ログを確認したいプロジェクトを選択
ログビューワーは1プロジェクトに対して1つ提供されます。そのためログビューワーを利用する場合は前提としてプロジェクトを作成する必要があります。
画像1. Developer Console
3. 左メニューから[Monitoring(監視)]-[Logs(ログ)]を選択
これでログビューワー画面への遷移は完了です。起動中のアプリケーションがあればログの出力が確認できるかと思います。ただ、もちろんアプリケーションを動作していなければログの出力はおこなわれません。まだ未動作の場合は実際にアプリケーションを動作させて、ログが出力されることを確認してみましょう。
画像2. ログビューワー
ログのフィルタリング方法
次にビューワーからログのフィルタリングをおこなう方法について説明します。実際にいくつか実行例を出して説明します。
1. ステータスコードからログを検索したい場合
ステータスからログを検索したい場合は「status:」ラベルを利用します。2つ以上並べるとOR検索となります。以下の例はステータスコードが404、または500のログを検索する場合の条件例です。
画像3. ステータスによるログ検索
2. 特定文字列を含んだログを検索したい場合
任意の文字列を含むログを検索したい場合は「regex:」を利用します。以下はプログラムから吐き出した任意の文字列を検索するための条件例となります。もちろんマルチバイト文字列でもログの検索は可能です。
画像4. 任意文字列によるログ検索
3. methodからログを検索したい場合
特定のメソッドに該当するログを検索したい場合は「method:」を利用します。methodに指定できる値はGET/POST/PUT/DELETEのいずれかとなります。
画像5. メソッドによるログ検索
ログのダウンロード方法
AppEngineからログをダウンロードする場合はAppEngine SDKに同梱されているappcfg.shを利用します。コマンドのフォーマットは以下の通りです。
- ログダウンロードコマンド
./appengine-java-sdk/bin/appcfg.sh (1)request_logs (2)myapp/war (3)ログファイル.txt |
※コマンドの引数についての説明は以下の通りです。(1)は固定値となり、(2)(3)については任意の値を設定します。
1. request_logs
ログダウンロードを実行するためのコマンドとなります。
2. myapp/war
「アプリケーション名/war」を指定します。アプリケーション名にはダウンロード対象のアプリケーション名を指定します。
3. ログファイル.txt
ダウンロードされたログが書き込まれるログファイルのパスを指定します。ファイル名だけ指定した場合は、コマンド実行時のカレントディレクトリにログファイルが生成されます。
ログの読み方
リクエストを受信したアプリケーションについてログビューワーを確認すると、1リクエスト毎に以下のフォーマットでログが書き込まれていることがわかります。各項目についての説明は以下の通りです。
- ロブビューワー上のログフォーマット
(1)192.0.2.0 (2)test [(3)27/Jun/2014:09:11:47 -0700] “(4)GET / HTTP/1.1″ (5)200 (6)414 -“(7)http://www.example.com/index.html”(8)Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36″”(9)1-dot-calm-sylph-602.appspot.com” (10)ms=195 (11)cpu_ms=42 (12)cpm_usd=0.000046(13)loading_request=1 (14)instance=00c61b117cfeb66f973d7df1b7f4ae1f064d (15)app_engine_release=1.9.15 |
1. 192.0.2.0
アクセス元のクライアントIPを示します。
2. test
アクセスユーザの(Gmailアカウントの)ニックネームを示します。アクセスユーザがGoogleアカウントの認証ユーザである場合表示されます。
3. 27/Jun/2014:09:11:47 -0700
リクエストが発行された日時を示します。表示される日時は太平洋標準時(UTC -8:00)、または太平洋夏時間(UTC -7:00)のいずれかとなります。例として提示したログは太平洋夏時間中に出力されたログとなるため日時の末尾に”-700”と表示されています。夏時間外の期間の場合は太平洋標準時となるため”-800”が表記されます。
※下図のようにログビューワーではタイムゾーンの切り替えをおこなうことができます。ただ、切り替え後のログ情報の見出し(下図オレンジ枠)は日本時間が表記されますが、ログの詳細に記載される日時(下図赤枠)については、前述した通り太平洋標準時、または太平洋夏時間のどちらかが表示されることになります(JSTのフォーマット日時が記載されることはありません)。
画像6. タイムゾーンの切り替え
4. GET / HTTP/1.1
左から順にメソッドタイプ、アクセスパス、HTTPバージョンを示します。
5. 200
返却されたHTTPステータスコードを示します。
6. 414
レスポンスのデータサイズ(byte)を示します。
7. http://www.example.com/index.html
リクエスト元のURLを示します。
8. Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36
アクセス元端末のユーザーエージェントを示します。
9. 1-dot-calm-sylph-602.appspot.com
GAEアプリケーションに接続するためにクライアントが利用しているホストの名称を示します。
10. ms=195
AppEngineのリクエスト処理にかかるclock timeの総時間を示します。
11. cpu_ms=42
AppEngineのリクエスト処理にかかるCPU時間を示します。
12. cpm_usd=0.000046
1000リクエストでかかると推定される料金コストを示します。
13. loading_request=1
新しいJVMを生成するためのリクエストであるかを判別するための値となります。パラメータが1の場合はJVMの生成が行われます。
14. instance=00c61b117cfeb66f973d7df1b7f4ae1f064d
リクエストを処理するインスタンスの識別子を示します。
15. app_engine_release=1.9.15
アプリケーションのAppEngineバージョンを示します。
ログAPIの利用方法
ログAPIを利用すればアプリケーションから任意のログを出力することができます。JAVA、Python、Go,PHPそれぞれの言語に対応したAPIがGoogleから提供されていますが、本記事ではJAVAを利用した場合のログAPIの利用方法について説明します。
1. ログレベル
開発者はログレベルを使い分けながら任意のログ出力をおこなうことが可能です。もちろん出力したログはビューワーからも検索可能となります。
2. JAVAのサンプルプログラム
では、実際のログ出力をおこなうプログラムを実行させてみます。JAVAの場合によく利用する以下3つのレベルでログ出力をおこなってみます。好みによってはlog4jを利用したい方もいるとは思いますが今回はGAEデフォルトのロギング機能を利用します。INFO以上のログを出力する場合は”WEB-INF/logging.properties”を編集し、”.level”の値に”INFO”を設定してください。
- Info
- Warning
- Severe
import java.io.IOException;import java.util.logging.Logger;
import javax.servlet.http.*;
public class LoggingServlet extends HttpServlet {private static final Logger LOGGER = Logger.getLogger(LoggingServlet.class.getName());public void doGet(HttpServletRequest req, HttpServletResponse resp)throws IOException {LOGGER.info("info");LOGGER.warning("warning");LOGGER.severe("severe");}}

画像7. ログAPIから出力されたログ
まとめ
以上のことからGCPは非常に便利なロギング機構を開発者に提供してくれることがわかりました。まさに開発者指向のGCPらしい機能と言えます。特にGCP環境でアプリケーションを運用していく場合、強力なフィルタリング機能を搭載したログビューワーは問題が起きた場合の大きな助けになってくれると思います。
apps-gcpでは今後もシリーズとしてGAE Articlesの説明記事を紹介していきます。内容によっては初心者向けの記事もあるかと思いますが、経験者の方にとっても知識の確認となるはずですので、ぜひ今後もチェックをよろしくお願いします。