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

Jeffrey Scudder, Tim Google Data API
Juni 2007

Pengantar

Terkadang tidak ada pengganti untuk melihat apa yang dikirimkan melalui kabel. Hal ini terutama berlaku saat menulis software yang menggunakan layanan web seperti Google Data API, yang banyak operasinya melibatkan pembuatan permintaan HTTP. Jika semua cara gagal, Anda dapat memverifikasi bahwa program Anda melakukan apa yang Anda harapkan dengan melihat byte yang sebenarnya dikirim dan diterima. Banyak library klien untuk Google Data API memiliki mode penelusuran bug yang menampilkan traffic HTTP. Hal ini sangat berguna jika Anda tidak memiliki akses ke penganalisis paket seperti WireShark atau Fiddler.

Saya tidak dapat menghitung berapa kali saya bersumpah bahwa program saya sudah benar, tetapi setelah memeriksa rekaman aktivitas paket, ternyata ada karakter baris baru tambahan, atau header HTTP yang salah nama. Memprogram layanan web tanpa melihat traffic HTTP bisa seperti mencoba memasukkan benang ke dalam jarum dengan mata tertutup.

Namun, Anda mungkin berada dalam situasi di mana penganalisis paket tidak tersedia atau tidak memadai untuk menangani paket terenkripsi. Jangan khawatir, Anda dapat mengatasi batasan ini dengan memanfaatkan beberapa mekanisme pencatatan dalam program. Dengan memanfaatkan fasilitas logging ini, Anda dapat melihat sebagian, jika tidak semua, data yang dipertukarkan, bahkan untuk data HTTPS terenkripsi 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. Dalam setiap contoh, saya mengaktifkan logging atau proses debug, melakukan autentikasi menggunakan login klien, lalu mendapatkan daftar Google Spreadsheet saya dan mencetak judulnya.

Java

Anda dapat menggunakan class java.util.logging untuk menyetel tingkat logging (dan akibatnya mengekspos data traffic) untuk beberapa objek utama di library klien. Dalam contoh di bawah, saya memilih untuk melihat header HTTP dan aktivitas parser XML untuk mendapatkan gambaran lengkap tentang apa yang dikirim melalui jaringan.

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

Instance logger akan mencatat aktivitas untuk HttpGDataRequest dan XmlParser, dan Anda dapat mengontrol tingkat detail output setiap logger. Untuk demonstrasi ini, saya 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 contoh kode 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 menghilangkan 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 bisa menjadi cukup besar, jadi sebaiknya Anda lebih selektif dalam menetapkan level Logger. Anda juga dapat membuat FileHandler, bukan ConsoleHandler, agar Anda dapat menyimpan data log untuk digunakan nanti.

Tentu saja, jika Anda tidak menyukai Java, Anda dapat mencoba .NET.

.NET

Untuk merekam 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 Layanan. 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 menyetel CombinedFileName.

Setelah menyiapkan factory permintaan, Anda perlu mengganti factory permintaan di objek Layanan dengan menyetel 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 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 sangat menyukai bahasa scripting, dan lebih suka menggunakan Python.

Python

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

Menetapkan debug ke benar (true) akan menetapkan tanda debug di objek HTTPRequest pokok yang ada dalam objek layanan.

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

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

Anda akan melihat sesuatu seperti ini di konsol:

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 ditampilkan di konsol.

Kesimpulan

Tutorial singkat ini telah mengilustrasikan 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 penganalisis paket. Saya baru menyentuh sebagian kecil dari contoh-contoh ini. Banyak mekanisme logging yang ada dalam bahasa ini jauh lebih canggih daripada yang ditampilkan di sini. Jika Anda ingin mengetahui informasi selengkapnya tentang logging atau Google Data API, lihat daftar referensi di bawah.

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

Item pusat informasi terkait:

Grup diskusi: Kami memiliki beberapa grup diskusi, dan akan ada lebih banyak grup diskusi saat lebih banyak Google Data API diluncurkan. Kami secara aktif memantau grup.

Jika ada pertanyaan atau saran, kami akan senang mendengarnya. Bergabunglah ke grup diskusi dan mulailah memposting.