概要
- AWS SDK for Rubyでは
http_wire_trace
オプションを利用するとAWS SDKがAPIと通信した内容を出力することができます。デバッグ時に便利です。 -
http_wire_trace
オプションはリソースやクライアントの初期化時に指定するかAWS.config
でグローバルに指定することもできます。 - 使い方は言語毎に異なりますが、少なくともPythonのboto3でも通信内容の出力は可能で、他の言語のSDKにも同様の機能があるようです。
前提ソフトウェア・ハードウェア
ソフトウェア | バージョン | 備考 |
---|---|---|
Ruby | 2.5.1p57 | - |
aws-sdk-core | 3.27.0 | - |
aws-sdk-sns | 1.5.0 | - |
Amazon SNSのpublishで通信内容を出力する例
AWS SDKを使ってコードを書いているとAWSのAPIとの通信内容を確認してデバッグしたくなることがあります。 そのような時はhttp_wire_trace
オプションを使うと便利です。
通信内容を出力しないサンプルコード
とあるAmazon SNSのトピックにPublishアクションを実行する以下のコードを例に通信内容を出力してみます。 このコードを実行すると、通常は何も出力されずに正常終了します。
require 'aws-sdk-sns'
topic = Aws::SNS::Topic.new(arn: 'arn:aws:sns:ap-northeast-1:9999999999999:some_topic')
topic.publish(message: 'Hello!')
通信内容を出力するよう改変したサンプルコード
ここでAws::SNS::Topic
の初期化時にhttp_wire_trace: true
オプションを指定してみます。 これでtopic
に代入されたAws::SNS::Topic
インスタンスで行った操作は通信内容が出力されるようになります。
require 'aws-sdk-sns'
topic = Aws::SNS::Topic.new(
arn: 'arn:aws:sns:ap-northeast-1:9999999999999:some_topic',
http_wire_trace: true # http_wire_trace: true を追加した
)
topic.publish(message: 'Hello!')
プログラムは正常終了しますが、以下の標準出力がされるようになります。 クレデンシャルなど機微な情報が含まれることに注意が必要です。
opening connection to sns.ap-northeast-1.amazonaws.com:443...
opened
starting SSL for sns.ap-northeast-1.amazonaws.com:443...
SSL established
<- "POST / HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded; charset=utf-8\r\nAccept-Encoding: \r\nUser-Agent: aws-sdk-ruby3/3.27.0 ruby/2.5.1 x86_64-linux-gnu aws-sdk-sns/1.5.0\r\nHost: sns.ap-northeast-1.amazonaws.com\r\nX-Amz-Date: 20180917T114946Z\r\nX-Amz-Content-Sha256: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\r\nAuthorization: AWS4-HMAC-SHA256 Credential=XXXXXXXXXXXXXXXXXXXX/20180917/ap-northeast-1/sns/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amzignature=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\r\nContent-Length: 120\r\nAccept: */*\r\n\r\n"
-> "HTTP/1.1 200 OK\r\n"
-> "x-amzn-RequestId: XXXXXXXX-XXXX-XXXX-XXXXXXXXXXXXXXXXX\r\n"
-> "Content-Type: text/xml\r\n"
-> "Content-Length: 294\r\n"
-> "Date: Mon, 17 Sep 2018 11:49:46 GMT\r\n"
-> "\r\n"
reading 294 bytes...
-> ""
-> "<PublishResponse xmlns=\"http://sns.amazonaws.com/doc/2010-03-31/\">\n <PublishResult>\n <MessageId>XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX</MessageId>\n </PublishResult>\n <ResponseMetadata>\n <RequestId>XXXXXXXX-XXXX-XXXX-XXXXXXXXXXXXXXXXX</RequestId>\n </ResponseMetadata>\n</PublishResponse>\n"
read 294 bytes
Conn keep-alive
同様の出力をする他のサンプルコード
クライアントやリソースのインスタンスに設定したhttp_wire_trace
は受け継がれていきます。 以下の2つの例ではAws::SNS::Topic
インスタンスそのものにはオプションを指定していませんがtopic.publish
で通信内容が出力されます。
require 'aws-sdk-sns'
sns = Aws::SNS::Resource.new(http_wire_trace: true) # Aws::SNS::Resourceでhttp_wire_trace: trueを指定
topic = sns.topic('arn:aws:sns:ap-northeast-1:9999999999999:some_topic') # Aws::SNS::ResourceからTopicを作成
topic.publish(message: 'Hello!')
require 'aws-sdk-sns'
sns_client = Aws::SNS::Client.new(http_wire_trace: true) # Aws::SNS::Clientでhttp_wire_trace: trueを指定
topic = Aws::SNS::Topic.new(arn: 'arn:aws:sns:ap-northeast-1:9999999999999:some_topic', client: sns_client) # Aws::SNS::Clientを渡してTopicを初期化
topic.publish(message: 'Hello!')
もし全てのAWSとの通信部分で出力したい場合はAws.config
でhttp_wire_trace
を指定すれば良いです。
require 'aws-sdk-sns'
Aws.config.update(http_wire_trace: true)
topic = Aws::SNS::Topic.new(arn: 'arn:aws:sns:ap-northeast-1:9999999999999:some_topic')
topic.publish(message: 'Hello!')
なおlogger
オプションを指定するとhttp_wire_trace
の出力もつられてlogger
の出力先に出るようになっています。 以下の例では標準エラー出力に通信内容が出力されます。
require 'aws-sdk-sns'
Aws.config.update(logger: Logger.new(STDERR), http_wire_trace: true) # loggerオプションに標準エラー出力向きのLoggerを指定している
topic = Aws::SNS::Topic.new(
arn: 'arn:aws:sns:ap-northeast-1:9999999999999:some_topic'
)
topic.publish(message: 'Hello!')
AWS SDK for Rubyのhttp_wire_trace
はどのように実装されているのか?
http_wire_trace
オプションによって出力をするかどうか切り替えている箇所はSeahorse::Client::NetHTTP::ConnectionPool
の以下の行です。
aws-sdk-ruby/connection_pool.rb at 2080dae8a525cf87ade12c65d1e06d3ee3c4ad26 · aws/aws-sdk-ruby
http.set_debug_output(logger) if http_wire_trace?
このコード中でhttp
はExtendedSession
クラス(RubyのNet::HTTP
のデリゲータ)のインスタンスです。 http_wire_trace
とはAWS SDK内部でNet::HTTP
のset_debug_output
にlogger
を渡すかどうかのフラグであることがわかります。
Net::HTTP#set_debug_output
はリファレンスを参照して下さい。 内部では<<
しているようです。
AWS SDKにlogger
を設定するとhttp_wire_trace
の出力先も変更されるのはこのためです。 ただし<<
で出力しているのでRubyのLogger
の実装ではフォーマットはされません。
instance method Net::HTTP#set_debug_output (Ruby 2.5.0)
set_debug_output(io) -> ()
デバッグ出力の出力先を指定します。 このメソッドは深刻なセキュリティホールの原因 になるため、デバッグ以外では決して使わないでください。
io に nil を指定するとデバッグ出力を止めます。
[PARAM] io:
出力先を指定します。このオブジェクトは メソッド « を持っている必要があります。
他の言語のAWS SDKで同様の機能はあるか
Pythonのboto3だとboto3.set_stream_logger
で出力可能でした。 RubyのコードをPythonで書き換えたサンプルコードは以下のとおりです。
Boto3 Reference – Boto 3 Docs 1.9.4 documentation
import boto3
boto3.set_stream_logger(name='')
sns = boto3.resource('sns')
topic = sns.Topic('arn:aws:sns:ap-northeast-1:999999999999:some_topic')
topic.publish(Message='Hello!')