Men-debug Klien Google Data API: Menjelajahi Traffic dari Dalam Program

Jeffrey Scudder, Tim Google Data API
Juni 2007

Pengantar

Terkadang, tidak ada pengganti untuk melihat apa yang melewati kabel. Terutama, ketika menulis software yang menggunakan layanan web seperti Google Data API, karena banyak operasi melibatkan pembuatan permintaan HTTP. Jika semuanya gagal, Anda dapat memverifikasi bahwa program Anda melakukan apa yang diharapkan dengan melihat byte yang dikirim dan diterima yang sebenarnya. Banyak library klien untuk Google Data API memiliki mode proses debug yang menampilkan traffic HTTP. Hal ini sangat berguna saat Anda tidak memiliki akses ke sniffer paket seperti WireShark atau Fiddler.

Saya tidak dapat menghitung berapa kali saya bersumpah bahwa program saya benar, hanya untuk menemukan setelah memeriksa pelacakan paket bahwa ada karakter baris baru tambahan, atau header HTTP yang salah diberi nama. Pemrograman terhadap layanan web tanpa melihat traffic HTTP dapat berfungsi seperti mencoba memasang benang dengan mata tertutup.

Namun, Anda mungkin mendapati diri Anda dalam situasi ketika sniffer paket tidak tersedia atau tidak memadai untuk menangani paket terenkripsi. Jangan khawatir, Anda dapat mengatasi batasan ini dengan memanfaatkan beberapa mekanisme logging dalam program. Dengan memanfaatkan fasilitas logging ini, Anda dapat melihat beberapa, atau tidak semua, data pertukaran, bahkan untuk data HTTPS yang dienkripsi atau kode yang berjalan dari jarak jauh.

Untuk artikel ini, saya telah menulis contoh kode diagnostik dalam 3 bahasa menggunakan library klien Google Data API untuk Java, .NET, dan Python. Di setiap contoh, saya mengaktifkan logging atau proses debug, mengautentikasi menggunakan login klien, lalu mendapatkan daftar Google Spreadsheet saya dan mencetak judulnya.

Java

Anda dapat menggunakan class java.util.logging untuk menetapkan level logging (dan akibatnya mengekspos data traffic) untuk beberapa objek utama dalam library klien. Pada contoh di bawah, saya memilih untuk melihat header HTTP dan aktivitas parser XML untuk mendapatkan gambaran lengkap tentang apa saja yang berjalan melalui kabel.

Library klien Java Data Google memiliki class terpisah untuk menangani permintaan HTTP dan penguraian XML; sehingga, saya perlu membuat dua objek Logger, satu untuk setiap class: com.google.gdata.client.http.HttpGDataRequest menangani traffic HTTP, sementara com.google.gdata.util.XmlParser bertanggung jawab untuk penguraian XML.

Instance pencatat akan merekam aktivitas untuk HttpGDataRequest dan XmlParser, dan Anda dapat mengontrol tingkat detail setiap output pencatat log. Untuk demonstrasi ini, saya telah memilih untuk melihat semua peristiwa yang dihasilkan oleh objek HttpGDataRequest dan XmlParser.

Setelah membuat dan mengonfigurasi Logger, saya perlu memberi tahu mereka apa yang harus dilakukan saat menerima peristiwa dari kelasnya. Untuk saat ini, saya ingin menulis semua informasi logging ke konsol, jadi saya membuat ConsoleHandler dan menambahkannya ke kedua Logger saya.

Berikut kode contoh saya:

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());
       
}
   
}
}

Saat menjalankan program ini, Anda akan melihat sesuatu seperti ini di konsol (saya memotong beberapa bagian yang kurang menarik):

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

Log ini dapat menjadi cukup besar, jadi Anda mungkin harus lebih selektif dalam menetapkan level Logger. Anda juga dapat membuat FileHandler, bukan ConsoleHandler, untuk memungkinkan Anda menyimpan data log untuk digunakan nanti.

Tentu saja, jika Java bukan tas Anda, Anda dapat mencoba .NET.

.NET

Untuk menangkap traffic HTTP di library klien .NET, Anda dapat mengganti factory permintaan default di klien dengan GDataLoggingRequestFactory.

Permintaan HTTP di library .NET dibuat oleh GDataRequestFactory yang ada di dalam setiap objek Service. Factory permintaan normal tidak melakukan logging apa pun, tetapi GDataLoggingRequestFactory, yang merupakan subclass dari GDataRequestFactory, memiliki logging bawaan. Anda dapat menentukan jalur lengkap file log dengan menetapkan CombinedFileName.

Setelah menyiapkan factory permintaan, Anda perlu mengganti factory permintaan di objek Service dengan menetapkan RequestFactory objek layanan. Kode Anda mungkin terlihat seperti ini:

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();
       
}
   
}
}

File log yang dihasilkan berisi permintaan dan respons XML. Berikut adalah contoh singkat yang telah saya format menggunakan 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>

Namun, mungkin Anda benar-benar menyukai bahasa skrip, dan Anda lebih suka menggunakan Python.

Python

Untuk merekam traffic HTTP dalam library klien Python, Anda dapat melakukan echo traffic header HTTP ke konsol dengan mengaktifkan mode debug di klien HTTP. Objek layanan memiliki anggota debug yang dapat Anda setel ke True.

Menyetel debug ke true akan menetapkan flag debug di objek HTTPRequest pokok yang terdapat dalam objek layanan.

Berikut adalah contoh yang akan melakukan echo header HTTP yang dikirim dari server spreadsheet saat Anda meminta daftar spreadsheet.

#!/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

Dan Anda akan melihat sesuatu seperti ini di konsol Anda:

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

Saat melakukan operasi tambahan, seperti penyisipan atau pembaruan, Anda akan melihat data permintaan yang sesuai bergema ke konsol.

Kesimpulan

Tutorial singkat ini telah menggambarkan cara menambahkan fungsi logging dasar ke dalam program Java, .NET, atau Python yang menggunakan library klien Google Data API. Teknik ini dapat berguna jika Anda perlu men-debug pertukaran HTTP, tetapi tidak memiliki akses ke sniffer paket. Saya hanya membahas sebagian kecil contoh. Banyak mekanisme logging yang ada dalam bahasa ini jauh lebih canggih daripada yang ditampilkan di sini. Jika Anda memerlukan informasi selengkapnya tentang logging atau Google Data API, lihat daftar resource di bawah ini.

Library klien yang dibahas dalam artikel ini dapat ditemukan di halaman berikut:

Item pusat informasi terkait:

Grup diskusi: Ada cukup banyak grup diskusi, yang akan hadir lebih banyak lagi seiring diluncurkannya lebih banyak Google Data API. Kami secara aktif memantau grup.

Jika ada pertanyaan atau saran, kami siap membantu Anda. Buka grup diskusi dan mulailah memposting.