問題
要するに、どこかで例外がスローされ、どこで今までエラーを再現できなかったのかわかりません。これは一部の人にのみ発生し、あなたには発生しません。エラーログに表示されるので、他の人にも発生することがわかります。
問題を再現する
すでに一般的な理由を排除しているので、エラーを再現する必要があります。エラーの原因となるパラメータがわかっている場合は、エラーを簡単に見つけることができます。
- ほとんどの場合、すべてのPOST/GETパラメーターを知っていれば十分です。
- これらだけでは再現できない場合は、追加のリクエストヘッダーを知っておく必要があります。ユーザーエージェント、accept-encoding、...など
- それでも再現できない場合は、非常に困難になります。エラーは、状態(セッション)、現在の時刻、送信元IPアドレスなどによって異なる場合があります。
カスタムログ方式
簡単に始めましょう:すべてのパラメーターを取得するには、影響を受けるphpファイルの最初に次のように記述できます。
file_put_contents("/path/to/some/custom_error_log", date()."\n".print_r(get_defined_vars(), true), FILE_APPEND | LOCK_EX);
custom_error_logファイルはphpアプリケーションに書き込み可能でなければならないことを忘れないでください。次に、エラーログでエラーが発生した場合は、custom_error_logファイルで対応する行を見つけます。うまくいけば、リクエストを識別できるように、1秒あたりのリクエスト数はそれほど多くありません。たぶん、ソースIPのようなエラーログのいくつかの追加パラメータは、リクエストを識別するのに役立ちます(エラーログにそれが示されている場合)。そのデータから、同じPOST/GETパラメーターを使用してリクエストを再構築します。
tcpdumpメソッド
同様に非常に単純ですが、ターゲットマシンにrootアクセス権が必要な次のオプションは、tcpflowをインストールすることです。次に、フォルダを作成し、そのフォルダにcdして、(rootとして)実行しますtcpflow "port 80"
。オプション(ポート80)はpcapフィルター式です。それでできることをすべて見るには、を参照してくださいman pcap-filter
。これらのフィルター式でできることはたくさんあります。
これで、tcpflowはポート80ですべてのtcp接続を記録し、1つの接続に属するパッケージを組み合わせて完全なデータ交換を再構築し、このデータをファイルにダンプして、接続ごとに2つの新しいファイルを作成します。1つは着信データ用、もう1つは発信データ用です。次に、エラーログのタイムスタンプとファイルの最後に変更されたタイムスタンプに基づいて、エラーの原因となった接続のファイルを見つけます。次に、完全なhttpリクエストヘッダーを取得します。これで、同じaccept-encoding、user-agentなどの設定を含め、HTTPリクエストを完全に再構築できます。リクエストを直接netcatにパイプして、正確なリクエストを再生することもできます。ただし、sessionidのようないくつかの引数が邪魔になる可能性があることに注意してください。phpがセッションの有効期限が切れていることを検出した場合、ログインまたは予期しない何かにリダイレクトされる可能性があります。
もっと物事をあざける
これが役に立たず、マシンでエラーを再現できない場合は、モックするのが難しいすべてのものをモックすることを試みることができます。たとえば、ソースIPアドレス。これにより、いくつかのスタントが必要になる場合がありますが、それは可能です。「-w」オプションを指定したsshを使用してサーバーに接続し、トンネルインターフェイスを作成できます。次に、問題のあるIPアドレスを自分のマシンに割り当て、特定のIPにトンネルを使用するようにルート(route add host)ルールを設定します。2台のコンピューターを直接ケーブルで接続できる場合は、トンネルなしでもケーブルを接続できます。
最も重要なセッションをあざけるのを忘れないでください。print_r(get_defined_vars())を使用したメソッドを使用して、すべてのセッション変数を読み取ることができます。次に、まったく同じ変数を使用してセッションを作成する必要があります。
ユーザーに尋ねる
別のオプションは、実際にユーザーに何をしているかを尋ねることです。たぶん、あなたは彼と同じ手順をたどることができ、再現することができます。
これのどれも役に立たない場合
それが役に立たない場合...まあ...それからそれは深刻に困難になります。IPのことはすでに非常にありそうもないです。特定の地域のIPでエラーを引き起こすのはGEO-IPライブラリである可能性がありますが、これらはすべてかなりありそうもないことです。上記のいずれも問題の再現に役立たなかった場合は、custom_log_file-call/tcpflowによって生成されたすべてのデータで正しいリクエストが見つからなかった可能性があります。より正確なタイムスタンプを取得して、チャンスを増やしてください。date()の代わりにphpでmicrotime()を使用できます。エラーログで秒よりも正確な情報を取得できる場合は、Webサーバーを確認してください。より正確なタイムスタンプを提供する「tail」の独自の実装を作成します...システムの負荷を軽減して、それほど多くのデータから選択する必要がないようにします(別の時刻を試してください。
再現できたら問題を丸で囲みます
再現できたら、実際の原因を見つけるために公園を散歩する必要があります。エラーの原因となるパラメータは、試行錯誤するか、エラーの原因となった他のリクエストと比較して、類似点を探すことで見つけることができます。次に、このパラメーターの機能、アクセスするライブラリなどを確認できます。再現できなくなるまで、パラメーターを使用するすべてのコンポーネントを1つずつ無効にすることができます。次に、コンポーネントを入手して、問題をさらに深く掘り下げることができます。
見つけたものを教えてください。気になります ;-)。