июнь 2007 г.
Введение
Иногда ничто не заменит наблюдения за тем, что происходит по сети. Это особенно актуально при написании программного обеспечения, которое использует веб-службы, такие как API данных Google, где многие операции включают выполнение HTTP-запросов. Когда ничего не помогает, вы можете убедиться, что ваша программа делает то, что вы ожидаете, увидев фактически переданные и полученные байты. Многие клиентские библиотеки для API данных Google имеют режим отладки, в котором отображается HTTP-трафик. Это особенно полезно, когда у вас нет доступа к анализаторам пакетов, таким как WireShark или Fiddler .
Я не могу сосчитать, сколько раз я мог поклясться, что моя программа была правильной, только чтобы обнаружить при проверке трассировки пакета лишний символ новой строки или неправильно названный заголовок HTTP. Программирование для веб-службы без просмотра HTTP-трафика может быть похоже на попытку вдеть нить в иголку с закрытыми глазами.
Однако вы можете оказаться в ситуации, когда анализатор пакетов недоступен или не подходит для работы с зашифрованными пакетами. Не бойтесь — вы можете обойти это ограничение, используя некоторые встроенные в программу механизмы ведения журналов. Используя эти средства ведения журналов, вы можете увидеть некоторые, если не все, обмениваемые данные, даже для зашифрованных данных HTTPS или удаленного исполняемого кода.
Для этой статьи я написал пример диагностического кода на трех языках с использованием клиентских библиотек Google Data API для Java , .NET и Python . В каждом примере я включаю ведение журнала или отладку, аутентифицируюсь с использованием клиентского входа, а затем получаю список своих таблиц Google и распечатываю их заголовки.
Джава
Вы можете использовать классы java.util.logging
, чтобы установить уровни ведения журнала (и, следовательно, предоставить данные о трафике) для пары ключевых объектов в клиентской библиотеке. В приведенном ниже примере я решил просмотреть заголовки HTTP и действия синтаксического анализатора XML, чтобы получить полное представление о том, что передается по сети.
В клиентской библиотеке Google Data Java есть отдельные классы для обработки HTTP-запросов и анализа XML; таким образом, мне нужно создать два объекта Logger, по одному для каждого класса: com.google.gdata.client.http.HttpGDataRequest
обрабатывает HTTP-трафик, а com.google.gdata.util.XmlParser
отвечает за синтаксический анализ XML.
Экземпляры средства ведения журнала будут записывать действия для HttpGDataRequest
и XmlParser
, и вы можете контролировать уровень детализации выходных данных каждого средства ведения журнала. Для этой демонстрации я решил просмотреть все события, созданные объектами HttpGDataRequest
и XmlParser
.
После того, как я создал и настроил свои регистраторы, мне нужно сказать им, что делать, когда они получают событие от своих классов. На данный момент я хочу выводить всю информацию журнала на консоль, поэтому я создаю ConsoleHandler
и добавляю его в оба моих регистратора.
Вот мой пример кода:
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
Эти журналы могут быть довольно большими, поэтому вы можете быть более избирательны в настройке уровней регистраторов. Вы также можете создать FileHandler
вместо ConsoleHandler
, чтобы сохранить данные журнала для последующего использования.
Конечно, если вам не нравится Java, вы можете попробовать .NET.
.СЕТЬ
Для захвата HTTP-трафика в клиентской библиотеке .NET можно заменить фабрику запросов по умолчанию в клиенте на GDataLoggingRequestFactory
.
Запросы HTTP в библиотеке .NET создаются GDataRequestFactory
, которая находится внутри каждого объекта службы. Обычные фабрики запросов не ведут никакого ведения журнала, но GDataLoggingRequestFactory
, который является подклассом GDataRequestFactory
, имеет встроенное ведение журнала. Вы можете указать полный путь к файлу журнала, установив 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.
питон
Чтобы захватить HTTP-трафик в клиентской библиотеке Python, вы можете вывести трафик заголовков 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
При выполнении дополнительных операций, таких как вставка или обновление, вы увидите соответствующие данные запроса, отраженные на вашей консоли.
Заключение
В этом кратком руководстве показано, как можно добавить базовые функции ведения журналов в программу Java, .NET или Python, использующую клиентские библиотеки Google Data API. Эти методы могут быть полезны, если вам нужно отлаживать HTTP-обмены, но у вас нет доступа к анализатору пакетов. Я только поцарапал поверхность с этими примерами. Многие механизмы ведения журналов, присутствующие в этих языках, намного мощнее, чем показано здесь. Если вам нужна дополнительная информация о ведении журналов или API данных Google, ознакомьтесь со списком ресурсов ниже.
Клиентские библиотеки, описанные в этой статье, можно найти на следующих страницах:
Связанные элементы базы знаний:
- Как получить информацию журнала HTTP в клиентской библиотеке Java?
- Как получить информацию журнала HTTP в клиентской библиотеке .NET?
- Какие есть хорошие инструменты для отладки HTTP?
- Что такое API таблиц Google?
Дискуссионные группы. У нас их довольно много, и их число будет увеличиваться по мере развертывания новых API данных Google. Мы активно следим за группами.
Если у вас есть вопросы или предложения, я буду рад услышать от вас. Зайдите в группу обсуждения и начните публиковать.