httptapでターミナルからHTTPリクエストを解析する
外部サービスや内部マイクロサービスが突然遅延を始めたとき、自然と古いcurlに手が伸びるものです。しかし、标准的なcurlはレスポンスボディしか出力せず、接続フェーズのタイミングを抽出するには、--write-outフラグで десяток variablesを使った巨大なテンプレートを構築する必要があります。あるいはブラウザを起動してDevToolsのNetworkタブを開き、美しいウォーターフォールチャートに感心するでしょう。しかし、リモートサーバーのコンソールではブラウザを開けないため、生の出力の中を掘り下げるのは面倒です。
最近httptapを見つけました。DNS、TCPハンドシェイク、TLSネゴシエーション、TTFB(Time To First Byte)、レスポンスボディ転送といったHTTPリクエストを構成するフェーズ別に分解する、便利なPythonツールです。これらすべてがコンソール上で明確なウォーターフォールチャートとして表示されます。
内部構造と必要な理由
このツールはPythonで構築されており、httpx、httpcore、dnspython、Richライブラリを使用しています。合計応答時間だけを測定するのではなく、ネットワークスタックのトレーシングにフックして、リクエストがどの段階で停滞したかを正確に示します。

httpstatプロジェクトを使ったことがある人なら想法は馴染み深いでしょう。しかしhttptapにはいくつか重要な違いがあります:
- リダイレクトチェーンを追跡して各ステップのタイミングを個別に測定し、要約テーブルを表示できます。
- 人間可読な終了コードでレイテンシバジェット(SLO)チェックをサポート。
- TLS証明書を検査:ホスト名(CN)、暗号アルゴリズム、プロトコルバージョン、期限切れまでの日数を報告。
- すべてのメトリクスを含む構造化JSONをエクスポートして自動化に対応。
- curlフラグを理解するため(
-X、-H、-d、-L、-o)、指を再トレーニングする必要がありません。
インストールと実行方法
macOSまたはLinuxにHomebrewでインストールするのが最も簡単な方法です:
brew install httptap
Pythonツールを好む場合は、pipまたはuvも使用できます:
uv pip install httptap
# или
pip install httptap
GitHub Packagesレジストリには готовый Dockerイメージもあります:
docker run --rm ghcr.io/ozeranskii/httptap:latest https://example.com
基本的な使用法は簡単です:
httptap https://httpbin.io/get
ツールはリクエストを実行し、各ステップのタイミング、ステータスコード、ネットワーク情報(HTTP/2プロトコルバージョンとIPv4/IPv6アドレスファミリーを含む)を含む整然としたテーブルを出力します。
実際のツールできること
任意のHTTPメソッドとリクエストボディの操作
ツールはJSONやXMLを問題なく送信します。-dフラグを渡してメソッドを明示的に指定しない場合、ツールは自動的にPOSTに切り替わり、curlの動作を模倣します:
httptap https://httpbin.io/post --data '{"status": "testing", "source": "httptap"}'
データがファイルにある場合は、@構文でパスを渡せます:
httptap https://httpbin.io/post --data @payload.json
他のメソッドには、おなじみの-Xフラグ(または--request)があります:
httptap https://httpbin.io/put --method PUT --data '{"key": "value"}'
リダイレクトチェーンの追跡
301や302レスポンスのシリーズにどれだけの時間がかかるかを正しく表示できるツールはほとんどありません。-Lフラグ(または--follow)を追加するだけです:
httptap --follow https://httpbin.io/redirect/2

出力には各中間ホストの詳細な内訳と、合計時間を含む最終行が含まれます。
CIでのレイテンシバジェットのチェック
プロジェクトで最も有用な機能の一つが--slo-budgetフラグです。ツールをビルドパイプラインのスモークテストおよびゲート楽器として機能させます:
httptap --slo total=500,ttfb=200 https://api.example.com/health
ターゲットサービスが200ステータスで応答しても、TTFBが200ミリ秒を超えるか合計時間が500ミリ秒を超えると、ツールは終了コード2を返します。ネットワークエラーが発生した場合はコード75を返します(BSD sysexits標準によるEX_TEMPFAIL)。
コードの分離により、ネットワーク障害とパフォーマンス低下を区別するようにデプロイスクリプトを設定できます:
httptap --slo total=1500,tls=200 https://staging.example.com/
case $? in
0) echo "Сервис уложился в нормативы" ;;
4) echo "Нарушен SLO по времени ответа"; exit 1 ;;
75) echo "Временный сетевой сбой, повторяем проверку" ;;
esac
スクリプティングとコンパクトな出力
自動化やcronジョブには、Richのグラフィカル出力が過剰になることがあります。こんなシナリオ向けに2つのモードが利用可能です:
-
ログ用のコンパクトラインモード
--compact:httptap --compact https://httpbin.io/get -
メトリクステキストストリーム
--metrics:httptap --metrics-only https://httpbin.io/get次のような単一行が返ってきます:
Step 1: dns=30.1 connect=97.3 tls=199.0 ttfb=472.2 total=476.0 status=200 bytes=389 ip=44.211.11.205 family=IPv4 tls_version=TLSv1.2 proxy=direct -
--jsonによるJSONエクスポートではタイミング、ヘッダー、TLSパラメータ、IPアドレスが保存されます。
カスタムリゾルバーと拡張性
内部Pythonユーティリティを作成している場合、httptapはライブラリとして使用できます。アーキテクチャはプロトコル(typing.Protocol)に基づいているため、コンポーネントは簡単に交換可能です。例えば、/etc/hostsファイルを修正せずに特定のIPの応答をテストするためにDNSリゾルバをオーバーライドできます:
from httptap import HTTPTapAnalyzer, SystemDNSResolver
class StaticDNS(SystemDNSResolver):
def resolve(self, host, port, timeout):
return "93.184.216.34", "IPv4", 0.05
analyzer = HTTPTapAnalyzer(dns_resolver=StaticDNS())
steps = analyzer.analyze_url("https://example.com")
for step in steps:
print(f"TTFB: {step.timing.ttfb_ms:.2f} ms")
このツールはコンパクトで高速であり、1つの特定のタスクに焦点を当てています。生のcurlと重いグラフィカルプロファイラーの間のギャップをうまく埋めています。
このユーティリティは、サーバーでの遅いエンドポイントの迅速な診断のための運用エンジニア、外部APIレイテンシを測定するバックエンド開発者、パイプラインでSLOをチェックするQAチームにとって便利です。ローカルにインストールして、通常のcurlを数日間置き換えてみてください。可視化の明瞭さの差はすぐにわかります。
関連プロジェクト