Ubuntu16.04でログモジュールをNginxに追加する方法
序章
サーバー管理は、サービスの初期構成だけではありません。 また、これらのサービスを監視し、可能な限りスムーズに実行されていることを確認することも含まれます。 管理者にとって最も重要な知識源の1つは、システムイベントに関する情報を含むログファイルです。
NginxなどのWebサーバーの場合、ログには、Webサーバーを介してリソースにアクセスする各試行に関する貴重な情報が含まれます。 各Webサイトの訪問者と表示された画像、またはダウンロードされたファイルは、ログに細心の注意を払って登録されます。 エラーが発生すると、それらもログに保存されます。 適切に構造化されたログファイルを操作する方がはるかに簡単です。
このガイドでは、Nginxのロギングモジュールを利用する方法を見ていきます。 サーバーブロックごとに個別のログファイルを設定してから、ログ出力をカスタマイズします。 また、リクエストに関する追加情報(このチュートリアルの例では、リクエストの処理にかかる時間)を、Nginxにデフォルトで含まれているものを超えてアクセスログに追加します。
前提条件
このチュートリアルに従うには、次のものが必要です。
-
この初期サーバーセットアップチュートリアルでセットアップされた1つのUbuntu16.04サーバー(sudo非rootユーザーを含む)。
-
Ubuntu 16.04チュートリアルにNginxをインストールする方法に従って、サーバーにNginxをインストールします。
ステップ1—テストファイルの作成
このステップでは、デフォルトのNginxWebサイトディレクトリにいくつかのテストファイルを作成します。 これらを使用して、ロギング構成をテストします。
Nginx(またはその他のWebサーバー)がファイルのHTTP要求を受信すると、そのファイルを開き、そのコンテンツをネットワーク経由で転送することでユーザーに提供します。 ファイルが小さいほど、転送速度は速くなります。 ファイルが完全に転送されると、リクエストは完了したと見なされ、転送ログに記録されます。
このチュートリアルの後半では、ロギング構成を変更して、各リクエストにかかった時間に関する有用な情報を含めます。 変更された構成をテストし、さまざまな要求の違いに気付く最も簡単な方法は、さまざまな時間で送信されるさまざまなサイズの複数のテストファイルを作成することです。
truncate
を使用して、デフォルトのNginxディレクトリに1mb.test
という名前の1メガバイトのファイルを作成しましょう。
- sudo truncate -s 1M /var/www/html/1mb.test
同様に、サイズの異なる2つのファイル(最初は10メガバイト、次に100メガバイト)を作成し、それに応じて名前を付けます。
- sudo truncate -s 10M /var/www/html/10mb.test
- sudo truncate -s 100M /var/www/html/100mb.test
最後になりましたが、空のファイルも作成しましょう。
- sudo touch /var/www/html/empty.test
次のステップでこれらのファイルを使用してログファイルにデフォルト構成を入力し、チュートリアルの後半でカスタマイズされた構成を示します。
ステップ2—デフォルト構成を理解する
ログモジュールはコアNginxモジュールです。つまり、使用するために個別にインストールする必要はありません。 ただし、デフォルトの構成は最低限です。 このステップでは、デフォルト構成がどのように機能するかを確認します。
新規インストールでは、Nginxはすべてのリクエストをアクセスログとエラーログの2つの別々のファイルに記録します。 /var/log/nginx/error.log
にあるエラーログには、異常なサーバーエラー、またはリクエストの処理中のエラーに関する情報が格納されます。
/var/log/nginx/access.log
にあるアクセスログがより頻繁に使用されます。 Nginxへのすべてのリクエストに関する情報が保存される場所です。 このログでは、特に、ユーザーがアクセスしているファイル、ユーザーが使用しているWebブラウザー、ユーザーが持っているIPアドレス、およびNginxが各リクエストに応答したHTTPステータスコードを確認できます。
アクセスログファイルの行例を見てみましょう。 まず、ステップ1で作成した空のファイルをNginxにリクエストして、ログファイルが空にならないようにします。
- curl -i http://localhost/empty.test
応答として、いくつかのHTTP応答ヘッダーが表示されます。
HTTP/1.1 200 OK
Server: nginx/1.10.0 (Ubuntu)
Date: Thu, 30 Jun 2016 18:10:15 GMT
Content-Type: application/octet-stream
Content-Length: 0
Last-Modified: Thu, 30 Jun 2016 18:10:07 GMT
Connection: keep-alive
ETag: "5775607f-0"
Accept-Ranges: bytes
この応答から、いくつかのことを学ぶことができます。
HTTP/1.1 200 OK
は、Nginxが200 OK
ステータスコードで応答し、エラーがなかったことを示しています。Content-Length: 0
は、返されるドキュメントの長さがゼロであることを意味します。- リクエストは
Thu, 30 Jun 2016 18:10:15 GMT
で処理されました。
これがNginxがアクセスログに保存したものと一致するかどうかを見てみましょう。 ログファイルは管理ユーザーのみが読み取ることができるため、sudo
を使用してログファイルにアクセスする必要があります。
- sudo tail /var/log/nginx/access.log
ログには、以前に発行したテストリクエストに対応するこのような行が含まれます。
127.0.0.1 - - [30/Jun/2016:14:10:15 -0400] "GET /empty.test HTTP/1.1" 200 0 "-" "curl/7.47.0"
Nginxは、 Combined Log Format を使用します。これは、相互運用性のためにWebサーバーで一般的に使用されるアクセスログの標準化された形式です。 この形式では、各情報は1つのスペースで区切られます。 ハイフンは、欠落している情報を表します。
左から右へ、カテゴリは次のとおりです。
-
リソースを要求したユーザーのIPアドレス。
curl
をローカルで使用したため、アドレスはローカルホスト127.0.0.1
を指します。 -
リモートロギング情報。 Nginxはこの情報をサポートしていないため、ここでは常にハイフンになります。
-
HTTP基本認証に準拠したログインユーザーのユーザー名。 これは、すべての匿名リクエストでは空になります。
-
リクエスト日。 これは、応答ヘッダーの日付と一致していることがわかります。
-
リクエストパス。これには、リクエストメソッド(
GET
)、リクエストされたファイルへのパス(/empty.text
)、および使用されたプロトコル(HTTP/1.1
)が含まれます。 ])。 -
応答ステータスコードは
200 OK
で、成功を意味します。 -
転送されたファイルの長さ。ファイルが空だったため、ここでは
0
です。 -
HTTPリファラーヘッダー。リクエストが発信されたドキュメントのアドレスが含まれています。 この例では空ですが、これが画像ファイルの場合、リファラーは画像が使用されたページを指します。
HTTPリファラーヘッダーは、「リファラー」という単語のスペルミスです。これは、HTTPの起源に戻り、HTTP標準の一部です。
-
ユーザーエージェント、ここでは
curl
です。
アクセスログの単一のログエントリでさえ、リクエストに関する多くの貴重な情報が含まれています。 ただし、不足している重要な情報が1つあります。 http://localhost/empty.test
の正確な場所をリクエストしましたが、ログエントリには/empty.test
ファイルへのパスのみが含まれています。 ホスト名(ここでは、localhost
)に関する情報は失われます。
ステップ3—個別のアクセスログを構成する
次に、デフォルトのログ構成(Nginxがすべてのリクエストに対して1つのアクセスログファイルを保存する)をオーバーライドし、代わりにNginxがクリーンなNginxインストールに付属するデフォルトのサーバーブロック用に個別のログファイルを保存するようにします。 Ubuntu 16.04 チュートリアルでNginxサーバーブロック(仮想ホスト)を設定する方法を読むと、Nginxサーバーブロックに精通することができます。
サーバーブロックごとに個別のログファイルを保存して、さまざまなWebサイトのログを互いに効果的に分離することをお勧めします。 これにより、ログファイルが小さくなるだけでなく、重要なことに、ログを分析してエラーや疑わしいアクティビティを見つけやすくなります。
デフォルトのNginxサーバーブロック構成を変更するには、nano
またはお好みのテキストエディターでサーバーブロックNginx構成ファイルを開きます。
- sudo nano /etc/nginx/sites-available/default
次のようなserver
構成ブロックを見つけます。
. . .
# Default server configuration
#
server {
listen 80 default_server;
listen [::]:80 default_server;
. . .
赤でマークされた2本の線を構成に追加します。
. . .
# Default server configuration
#
server {
listen 80 default_server;
listen [::]:80 default_server;
access_log /var/log/nginx/default-access.log;
error_log /var/log/nginx/default-error.log;
. . .
access_log
ディレクティブは、アクセスログが保存されるファイルへのパスを設定し、error_log
はエラーログに対して同じことを行います。 デフォルトのNginxログ(/var/log/nginx
)と同じディレクトリを使用しますが、ファイル名は異なります。 複数のサーバーブロックがある場合は、ファイル名にドメイン名を使用するなど、一貫性のある意味のある方法でログファイルに名前を付けることをお勧めします。
ファイルを保存して閉じ、終了します。
注:サーバーブロックごとに個別のログファイルを維持するには、Nginx構成で新しいサーバーブロックを作成するたびに、前述の構成変更を適用する必要があることに注意してください。
新しい構成を有効にするには、Nginxを再起動します。
- sudo systemctl restart nginx
新しい構成をテストするには、空のテストファイルに対して以前と同じリクエストを実行します。
- curl -i http://localhost/empty.test
前に見たものと同じログ行が、構成したばかりの別のファイルに書き込まれていることを確認します。
- sudo tail /var/log/nginx/default-access.log
次のステップでは、この新しいファイルのログの形式をカスタマイズし、追加情報を含めます。
ステップ4—カスタムログ形式の設定
ここでは、カスタムログ形式を設定してNginxログに追加情報(リクエストの処理にかかった時間)を作成し、この新しい形式を使用するようにデフォルトのサーバーブロックを構成します。
使用する前に、新しいログ形式を定義する必要があります。 Nginxでは、各ログ形式に一意の名前があり、サーバー全体でグローバルです。 個々のサーバーブロックは、名前を参照するだけで、後でこれらの形式を使用するように構成できます。
新しいログ形式を定義するには、Nginxの追加の構成ディレクトリにtimed-log-format.conf
という新しい構成ファイルを作成します。
- sudo nano /etc/nginx/conf.d/timed-log-format.conf
次の内容を追加します。
log_format timed '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" $request_time';
ファイルを保存して閉じ、終了します。
log_format
設定ディレクティブは、新しいログ形式を定義します。 次の要素は、この形式の一意の識別子です。 ここではtimedを使用していますが、任意の名前を選択できます。
次は、読みやすくするために3行に分割されたログ形式自体です。 Nginxは、ドル記号が前に付いた名前付きシステム変数のすべてのリクエストに関する情報を公開します。 これらは、リクエストの詳細をアクセスログに書き込むときに、リクエストに関する実際の情報に置き換えられます(たとえば、$request_addr
は訪問者のIPアドレスに置き換えられます)。
上記の形式は、前に説明した共通ログ形式と同じですが、最後に$request_time
システム変数が追加されている点が1つ異なります。 Nginxはこの変数を使用して、リクエストにかかった時間をミリ秒単位で保存します。この変数をログ形式で使用することにより、Nginxにその情報をログファイルに書き込むように指示します。
これで、 timed という名前のカスタムログ形式がNginx構成で定義されましたが、デフォルトのサーバーブロックはまだこの形式を使用していません。 次に、サーバーブロックのNginx構成ファイルを開きます。
- sudo nano /etc/nginx/sites-available/default
以前に変更したserver
構成ブロックを見つけ、timed
ログ形式名をaccess_log
設定に追加します(以下の赤で強調表示)。
. . .
# Default server configuration
#
server {
listen 80 default_server;
listen [::]:80 default_server;
access_log /var/log/nginx/default-access.log timed;
error_log /var/log/nginx/default-error.log;
. . .
ファイルを保存して閉じ、終了します。
新しい構成を有効にするには、Nginxを再起動します。
- sudo systemctl restart nginx
すべてがセットアップされたので、それが機能することを確認しましょう。
ステップ5—新しい構成を確認する
手順2で行ったように、curl
を使用してNginxにいくつかのリクエストを呼び出すことで、新しい構成をテストできます。 今回は、手順1で作成したサンプルファイルを使用します。
- curl -i http://localhost/empty.test
- curl -i http://localhost/1mb.test
- curl -i http://localhost/10mb.test
- curl -i http://localhost/100mb.test
ファイルが大きくなり、転送に時間がかかるため、後続の各コマンドの実行に時間がかかることがわかります。
これらのリクエストを実行した後、アクセスログを表示してみましょう。
- sudo tail /var/log/nginx/default-access.log
ログにはさらに多くの行が含まれますが、最後の4つは実行したばかりのテスト要求に対応します。
127.0.0.1 - - [04/Jul/2016:14:57:02 -0400] "GET /empty.test HTTP/1.1" 200 0 "-" "curl/7.47.0" 0.000
127.0.0.1 - - [04/Jul/2016:14:57:51 -0400] "GET /1mb.test HTTP/1.1" 200 1048576 "-" "curl/7.47.0" 0.000
127.0.0.1 - - [04/Jul/2016:14:57:57 -0400] "GET /10mb.test HTTP/1.1" 200 10485760 "-" "curl/7.47.0" 1.901
127.0.0.1 - - [04/Jul/2016:14:58:52 -0400] "GET /100mb.test HTTP/1.1" 200 104857600 "-" "curl/7.47.0" 49.232
パスは毎回異なり、正しいファイル名が表示され、リクエストサイズは毎回増加します。 重要な部分は、最後に強調表示された数値です。これは、カスタムログ形式で構成したばかりの要求処理時間(ミリ秒単位)です。 ご想像のとおり、ファイルが大きくなるほど、転送に時間がかかります。
その場合は、Nginxでカスタムログ形式を正常に構成しています。
結論
大きなファイルの転送に時間がかかることを確認することは特に有用ではありませんが、Nginxを使用して動的なWebサイトを提供する場合、リクエストの処理時間は非常に役立ちます。 Webサイトのボトルネックを追跡し、必要以上に時間がかかったリクエストを簡単に見つけるために使用できます。
$request_time
は、カスタムロギング構成で使用できるNginxが公開する多くのシステム変数の1つにすぎません。 その他には、たとえば、クライアントへの応答とともに送信される応答ヘッダーの値が含まれます。 ログ形式に他の変数を追加するのは、$request_time
で行ったのと同じようにログ形式の文字列に入れるのと同じくらい簡単です。 これは、Webサイトのログを構成するときに有利に使用できる強力なツールです。
Nginxログ形式で使用できる変数のリストは、Nginxのログモジュールのドキュメントで説明されています。