2007 年 6 月
はじめに
ワイヤを通過するものを確認する以外に方法がない場合もあります。これは、Google Data APIs などのウェブサービスを使用するソフトウェアを作成する場合に特に当てはまります。この場合、多くのオペレーションで HTTP リクエストの作成が必要になります。他の方法で確認できない場合は、実際に送受信されたバイト数を確認することで、プログラムが想定どおりに動作していることを確認できます。Google Data APIs のクライアント ライブラリの多くには、HTTP トラフィックを表示するデバッグモードがあります。これは、WireShark や Fiddler などのパケット スニファにアクセスできない場合に特に便利です。
プログラムが正しいと確信していたのに、パケット トレースを調べると、余分な改行文字があったり、HTTP ヘッダーの名前が間違っていたりしたことが何度あったか数え切れません。HTTP トラフィックを確認せずにウェブ サービスに対してプログラミングを行うのは、目をつぶって針に糸を通そうとするようなものです。
ただし、パケット スニファが使用できない場合や、暗号化されたパケットを処理するのに十分でない場合があります。ただし、プログラム内のロギング メカニズムを活用することで、この制限を回避できます。これらのロギング機能を利用すると、暗号化された HTTPS データやリモートで実行されているコードであっても、交換されたデータの一部またはすべてを確認できます。
この記事では、Java、.NET、Python 用の Google Data API クライアント ライブラリを使用して、3 つの言語でサンプル診断コードを作成しました。各例では、ロギングまたはデバッグをオンにし、クライアント ログインを使用して認証してから、Google スプレッドシートのリストを取得してタイトルを出力します。
Java
java.util.logging
クラスを使用すると、クライアント ライブラリ内のいくつかのキー オブジェクトのロギングレベルを設定できます(結果としてトラフィック データが公開されます)。次の例では、HTTP ヘッダーと XML パーサーのアクティビティを調べて、ネットワークを通過するものを完全に把握しています。
Google Data Java クライアント ライブラリには、HTTP リクエストと XML 解析を処理する個別のクラスがあります。そのため、クラスごとに 1 つずつ、2 つの Logger オブジェクトを作成する必要があります。com.google.gdata.client.http.HttpGDataRequest
は HTTP トラフィックを処理し、com.google.gdata.util.XmlParser
は XML 解析を担当します。
ロガー インスタンスは HttpGDataRequest
と XmlParser
のアクティビティを記録します。各ロガーの出力の詳細レベルを制御できます。このデモでは、HttpGDataRequest
オブジェクトと XmlParser
オブジェクトによって生成されたすべてのイベントを表示するように選択しました。
Logger を作成して構成したら、クラスからイベントを受信したときに何を行うかを Logger に伝える必要があります。ここでは、すべてのロギング情報をコンソールに出力したいので、ConsoleHandler
を作成して両方の Logger に追加します。
サンプルコードは次のとおりです。
import com.google.gdata.client.spreadsheet.*;
import com.google.gdata.data.spreadsheet.*;
import com.google.gdata.util.*;
import java.io.*;
import java.net.URL;
import java.util.*;
import java.util.logging.*;
public class PrintSpreadsheetsWithLogging {
public static void main(String [] args) throws AuthenticationException,
ServiceException, IOException {
// Configure the logging mechanisms.
Logger httpLogger = Logger.getLogger("com.google.gdata.client.http.HttpGDataRequest");
httpLogger.setLevel(Level.ALL);
Logger xmlLogger = Logger.getLogger("com.google.gdata.util.XmlParser");
xmlLogger.setLevel(Level.ALL);
// Create a log handler which prints all log events to the console.
ConsoleHandler logHandler = new ConsoleHandler();
logHandler.setLevel(Level.ALL);
httpLogger.addHandler(logHandler);
xmlLogger.addHandler (logHandler);
SpreadsheetService service = new SpreadsheetService("testing-loggingExampleApp-1");
service.setUserCredentials(email, password);
// Get a list of your spreadsheets.
URL metafeedUrl = new URL("http://spreadsheets.google.com/feeds/spreadsheets/private/full ");
SpreadsheetFeed feed = service.getFeed(metafeedUrl, SpreadsheetFeed.class);
// Print the title of each spreadsheet.
List spreadsheets = feed.getEntries();
for (int i = 0; i < spreadsheets.size(); i++) {
SpreadsheetEntry entry = (SpreadsheetEntry)spreadsheets.get(i);
System.out.println("\t" + entry.getTitle().getPlainText());
}
}
}
このプログラムを実行すると、コンソールに次のような内容が表示されます(興味のない部分は省略しています)。
Jun 7, 2007 10:24:50 AM ...HttpGDataRequest setPrivateHeader FINER: Authorization: <Not Logged> Jun 7, 2007 10:24:50 AM ...HttpGDataRequest setHeader FINER: User-Agent: ... ... Jun 7, 2007 10:25:20 AM ...HttpGDataRequest execute FINE: 200 OK Jun 7, 2007 10:25:20 AM ...HttpGDataRequest execute FINER: Date: Thu, 07 Jun 2007 17:25:24 GMT Jun 7, 2007 10:25:20 AM ...HttpGDataRequest execute FINER: null: HTTP/1.1 200 OK Jun 7, 2007 10:25:20 AM ...HttpGDataRequest execute FINER: Content-Type: application/atom+xml; charset=UTF-8 Jun 7, 2007 10:25:20 AM ...HttpGDataRequest execute FINER: Last-Modified: Thu, 07 Jun 2007 17:25:22 GMT ... Jun 7, 2007 10:25:20 AM ...XmlParser startElement FINE: Start element id Jun 7, 2007 10:25:20 AM ...XmlParser endElement FINE: End element id ... Jun 7, 2007 10:25:20 AM ...XmlParser startElement FINE: Start element title Jun 7, 2007 10:25:20 AM ...XmlParser startElement FINER: Attribute type='text' Jun 7, 2007 10:25:20 AM ...XmlParser endElement FINE: End element title ... Jun 7, 2007 10:25:20 AM ...XmlParser endElement FINE: End element entry ... Jun 7, 2007 10:25:20 AM ...XmlParser endElement FINE: End element feed
これらのログは非常に大きくなる可能性があるため、ロガーのレベルを設定する際は、より選択的に行うことをおすすめします。ConsoleHandler
の代わりに FileHandler
を作成して、ログデータを保存し、後で使用できるようにすることもできます。
もちろん、Java が得意でない場合は、.NET を試してみることもできます。
.NET
.NET クライアント ライブラリで HTTP トラフィックをキャプチャするには、クライアントのデフォルトのリクエスト ファクトリを GDataLoggingRequestFactory
に置き換えます。
.NET ライブラリの HTTP リクエストは、各 Service オブジェクト内にある GDataRequestFactory
によって作成されます。通常のリクエスト ファクトリはロギングを行いませんが、GDataRequestFactory
のサブクラスである GDataLoggingRequestFactory
にはロギングが組み込まれています。CombinedFileName
を設定すると、ログファイルのフルパスを指定できます。
リクエスト ファクトリを設定したら、サービス オブジェクトの RequestFactory
を設定して、サービス オブジェクトのリクエスト ファクトリを置き換える必要があります。コードは次のようになります。
using System;
using Google.GData.Client;
using Google.GData.Extensions;
using Google.GData.Spreadsheets;
namespace LogginTest
{
class Program
{
static void Main(string[] args)
{
SpreadsheetsService service = new SpreadsheetsService("-exampleApp-1");
service.setUserCredentials(email, password);
Google.GData.Client.GDataLoggingRequestFactory factory = new GDataLoggingRequestFactory("wise", "SpreadsheetsLoggingTest");
factory.MethodOverride = true;
factory.CombinedLogFileName = "c:\\temp\\xmllog.log";
Console.WriteLine("Log file name:" + factory.CombinedLogFileName);
service.RequestFactory = factory;
SpreadsheetQuery query = new SpreadsheetQuery();
SpreadsheetFeed feed = service.Query(query);
Console.WriteLine("Your spreadsheets:");
foreach (SpreadsheetEntry entry in feed.Entries)
{
Console.WriteLine(entry.Title.Text);
}
Console.ReadKey();
}
}
}
生成されたログファイルには、XML リクエストとレスポンスが含まれています。以下に、tidy を使用してフォーマットした例を簡略化して示します。
<?xml version='1.0' encoding='utf-8'?> <feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'> <id> http://spreadsheets.google.com/feeds/spreadsheets/private/full</id> <updated>2007-06-07T22:05: 02.674Z</updated> <link rel='self' type='application/atom+xml' href='http://spreadsheets.google.com/feeds/spreadsheets/private/full'> </link> ... <entry> <updated>2007-03-28T17:28:57.250Z</updated> <category scheme=' http://schemas.google.com/spreadsheets/2006' term='http://schemas.google.com/spreadsheets/2006#spreadsheet'> <title type='text'>events</title> <content type='text'>events</content> ... </entry> <entry> <updated>2007-05-25T22:11:08.200Z</updated> <category scheme=' http://schemas.google.com/spreadsheets/2006' term='http://schemas.google.com/spreadsheets/2006#spreadsheet'> </category> <title type='text'>UnitTest</title> <content type='text'>UnitTest</content> ... </entry> ... </feed>
スクリプト言語に精通していて、Python を使用したい場合もあるでしょう。
Python
Python クライアント ライブラリで HTTP トラフィックをキャプチャするには、HTTP クライアントでデバッグモードをオンにして、HTTP ヘッダー トラフィックをコンソールにエコーします。サービス オブジェクトには、True に設定できるデバッグ メンバーがあります。
デバッグを true に設定すると、サービス オブジェクトに含まれる基盤となる HTTPRequest
オブジェクトのデバッグ フラグが設定されます。
次の例では、スプレッドシートのリストをリクエストしたときに、スプレッドシート サーバーから送信された HTTP ヘッダーをエコーします。
#!/usr/bin/python
import gdata.spreadsheet.service
client = gdata.spreadsheet.service.SpreadsheetsService()
client.debug = True
client.ClientLogin(email, password)
feed = client.GetSpreadsheetsFeed()
for entry in feed.entry:
print entry.title.text
コンソールに次のような出力が表示されます。
reply: 'HTTP/1.1 200 OK\r\n' header: Content-Type: application/atom+xml; charset=UTF-8 header: Last-Modified: Thu, 07 Jun 2007 18:22:35 GMT header: Cache-Control: max-age=0, must-revalidate, private header: Transfer-Encoding: chunked ... header: Date: Thu, 07 Jun 2007 18:22:35 GMT header: Server: GFE/1.3
挿入や更新などのオペレーションを追加すると、対応するリクエスト データがコンソールにエコーバックされます。
まとめ
この簡単なチュートリアルでは、Google Data API クライアント ライブラリを使用する Java、.NET、Python プログラムに基本的なロギング機能を追加する方法について説明しました。これらの手法は、HTTP 交換をデバッグする必要があるが、パケット スニファにアクセスできない場合に役立ちます。これらの例は、ほんの一部にすぎません。これらの言語に存在するロギング メカニズムの多くは、ここで説明するよりもはるかに強力です。ロギングまたは Google Data API の詳細については、以下のリソースをご覧ください。
この記事で説明するクライアント ライブラリについては、次のページをご覧ください。
関連するナレッジベース アイテム:
- Java クライアント ライブラリで HTTP ロギング情報を取得するにはどうすればよいですか?
- .NET クライアント ライブラリで HTTP ロギング情報を取得するにはどうすればよいですか?
- HTTP デバッグに役立つツールを教えてください。
- Google Spreadsheets API とは何ですか?
ディスカッション グループ: 多数のグループがあり、Google Data API のロールアウトが進むにつれてさらに増える予定です。グループは常に監視されています。
ご質問やご提案がございましたら、お気軽にお問い合わせください。ディスカッション グループに参加して、投稿を開始します。