ログドレイン
この記事の英語版に更新があります。ご覧の翻訳には含まれていない変更点があるかもしれません。
最終更新日 2023年06月14日(水)
Table of Contents
Heroku の Logplex logging service (Logplex ログサービス) により、アプリケーションからログを収集し、それらのログを、Heroku の logging add-on providers (アドオンプロバイダーのログ) によって提供されるアーカイブ、検索、およアラートサービスに転送することが簡単になります。自身のログドレインを追加して、アプリケーションログの処理方法を完全に制御することもできます。
Heroku では、次の 2 種類のログドレインをサポートします。
- Syslog ドレイン
- HTTPS ドレイン
Syslog ドレイン
Syslog ドレインを使用すると、長期のアーカイブのために Heroku ログを外部 Syslog サーバーに転送できます。Heroku は、安全 (TLS) および安全でない Syslog ドレインの両方をサポートします。Heroku から Syslog パケットを受信できるように、ログサービス (またはご使用のサーバー) を設定してから、(ホストおよびポートを含む) Syslog URL を Syslog ドレインとして追加する必要があります。
ドレインログメッセージは、RFC5424 に従ってフォーマットされます。これらは、オクテットカウントフレーミング方法を使用して、RFC6587 の記述に従い TCP で配信されます。
Heroku は、Syslog 機能に local0、local3、および local7 を使用します。これは、いつでも変更に従います。
TLS Syslog
$ heroku drains:add syslog+tls://logs.example.com:12345 -a myapp
プレーンテキスト Syslog
$ heroku drains:add syslog://logs.example.com -a myapp
ドレイントークン
アプリケーションにドレインを追加すると、次のような一意のドレイントークンが割り当てられます。
d.9173ea1f-6f14-4976-9cf0-7cd0dafdcdbc
ドレイントークンは、対応するドレインから生じたすべてのログメッセージに書き込まれます。たとえば、次のようになります。
2013-01-01T01:01:01.000000+00:00 d.9173ea1f-6f14-4976-9cf0-7cd0dafdcdbc app[web.1] Your message here.
heroku drains --json
を実行することにより、アプリのログドレインのドレイントークンを取得できます。
$ heroku drains --json
[
{
"addon": null,
"created_at": "2018-12-04T00:59:46Z",
"id": "906262a4-e151-45d2-b35a-a2dc0ea9e688",
"token": "d.f14da5dc-106b-468d-b1bd-bed0ed9fa1e7",
"updated_at": "2018-12-04T00:59:47Z",
"url": "syslog://logs.example.com"
},
{
"addon": {
"id": "130dfc11-ca20-48ea-8a29-c0da56ea2c4f",
"name": "papertrail-curly-14926"
},
"created_at": "2018-10-26T21:44:01Z",
"id": "b8c04a36-c914-4ec4-a5bd-eaa8c965d0dd",
"token": "d.0b55c011-f49b-4428-ac2f-a5935fcffd50",
"updated_at": "2018-10-26T21:44:02Z",
"url": "syslog+tls://logs7.papertrailapp.com:41942"
}
]
上記の出力例は、アプリに 2 つのログドレインがあることを示します。一覧表示された最初のドレインは、ユーザーによって直接追加され (したがってその addon
フィルードは null
です)、2 番目のドレインは Papertrail アドオンによって追加されました。それぞれのドレインのトークンは、その token
フィールドで利用できます。
ドレイントークンを使用して、さまざまなドレインによって同じドレイン URL に送信されたログメッセージを分離します。別々のアプリ上の同じ URL へのドレインには、異なるドレイントークンが与えられます。ドレイントークンは、ドレインの生存期間中は同じままですが、同じドレインを削除して再度追加すると変更されます。
HTTPS ドレイン
ログドレインは、HTTPS を介したメッセージもサポートします。これにより、自身のログ処理ロジックを作成し、Web サービス (別の Heroku アプリなど) 上でそれを実行することが簡単になります。
Heroku が POST
リクエストを作成できるように、Web サービスを設定する必要があります。この場合、次のように HTTPS ドレインを追加します。
$ heroku drains:add https://user:pass@mylogdrain-1234567890ab.herokuapp.com/logs -a myapp
HTTPS ドレインを使用すると、Logplex はログメッセージをバッファに入れ、POST
リクエストによりこれらのバッチを HTTPS に送信します。POST
本文は、Syslog-formatted メッセージを含み、Syslog TCP プロトコルオクテットカウントフレーミング方法を使用して組み立てられます。これらのバッチは、application/logplex-1
の Content-Type
ヘッダーでポストされます。
Logplex POST
本文は次のようになります。
83 <40>1 2012-11-30T06:45:29+00:00 host app web.3 - State changed from starting to up
119 <40>1 2012-11-30T06:45:26+00:00 host app web.3 - Starting process with command `bundle exec rackup config.ru -p 24405`
次のリクエストヘッダーは、すべての Logplex POST
リクエストで送信されます。
Logplex-Msg-Count
: リクエストの本文にエンコードされたメッセージ数。上記の本文例では、この値は2
になります。このフィールドを使用して、本文を正しく解析したことを確認します。Logplex-Frame-Id
: このリクエストの一意の識別子。このリクエストが何らかの理由 (2xx 以外の応答コード、ネットワーク接続の失敗など) で再試行された場合、この識別子によって重複したリクエストを見つけられます。Logplex-Drain-Token
: リクエストを送信するログドレインの ドレイントークン。User-Agent
: これは Logplex のバージョンを記述します。Logplex リリース (Logplex/v72
など) とともに変化します。Content-Type
: このフィールドは、リクエストの本文のエンコードについて説明します。現在、この値は常にapplication/logplex-1
です。
HTTPS ドレインの注意事項
- Logplex は応答のチャンクされた転送エンコードをサポートしません。このため、応答の
Content-Length
ヘッダーを0
に設定し、本文を返さないでください。 application/logplex-1
のコンテンツタイプは、RFC 5424 に従いません。STRUCTURED-DATA
を省略しますが、NILVALUE
に置き換えることはありません。
セキュリティに関する考慮事項
HTTPS ドレインは、HTTPS プロトコルを使用したトランスポートレベルの暗号化と HTTP Basic 認証を使用した認証をサポートしています。Logplex では現在、すべての TLS および HTTP 接続でサーバー証明書を検証しています。以下の「ドレインのデバッグ」セクションの手順に従って、TLS Syslog ドレインを安全でないモードに切り替えることで、この機能をオプトアウトできます。
Syslog ドレインは、TLS ハンドシェイク中の証明書およびホスト名の検証など、トランスポートレベルの暗号化をサポートします。ただし、Logplex は、syslog ドレインの認証をサポートしません。したがって、サードパーティは、アドレスがわかっている場合、サーバーにログメッセージを送信できます。セキュリティ手段として、ドレイントークンが不明 (または欠落した) のメッセージをフィルターで除くことができます。
TLS Syslog ドレインは、TLS 1.2 や TLS 1.3 などの最新の TLS を完全にサポートします。
ドレインのデバッグ
TLS を Syslog ドレインとともに使用すると、証明書またはホスト名検証プロセスが失敗し、ドレインがログの受信を停止した可能性があります。これは、次のようなさまざまな理由で起きることがあります。
- 期限切れの証明書の使用
- 自己署名証明書の使用
- 証明書のホスト名の不一致
次のようなエラーが、heroku logs
コマンドで示されたログバッファに表示されます。エラーを取得するために、heroku logs -t
を使用して、しばらくの間アプリのログをストリーミングする必要がある場合があります。また、ログのストリーミング中に正しく動作しないドレインを削除し追加しなおすと、問題の追求に役立つことがあります。
TLS Syslog ドレインを安全でないモードに切り替えることもできます。これは、curl --insecure
と同様に機能します。トランスポートレベルの暗号化はアクティブなままですが、TLS ハンドシェイク中のすべての検証チェックが無効になります。Logplex は、#insecure
URI フラグメントを使用して、安全でないモードを有効にします。
$ heroku drains:add syslog+tls://logs.example.com:12345/#insecure -a myapp
ドレインの削除
heroku drains:remove
コマンドでアプリからログドレインを削除できます。
$ heroku drains:remove syslog+tls://logs.example.com:12345/#insecure -a myapp
ログドレインがアドオンによって作成された場合、手動では削除できません。アドオンを分離または破棄した場合、ログドレインは削除されます。