Google Data API İstemcilerinde Hata Ayıklama: Programınızdan Trafiği Keşfetme

Jeffrey Scudder, Google Veri API'leri Ekibi
Haziran 2007

Giriş

Bazen, kablonun ne üzerinde olduğunu görmenin alternatifi yoktur. Bu durum özellikle Google Verileri API'leri gibi web hizmetlerinin kullanıldığı yazılımlar yazarken çok sayıda işlemin HTTP isteğinde bulunması nedeniyle ortaya çıkar. Diğer her şey başarısız olduğunda, programınızın gerçekleştirilmiş ve alınan baytları görerek beklediğinizi yaptığını doğrulayabilirsiniz. Google Veri API'leri için istemci kitaplıklarının birçoğunda HTTP trafiğini gösteren bir hata ayıklama modu bulunur. Bu, özellikle WireShark veya Fiddler gibi bir paket yoklayıcıya erişiminiz olmadığında faydalıdır.

Programımın doğru olduğuna dair kaç kez yemin ettiğimi sayamıyorum. Yalnızca paket izini incelerken fazladan bir yeni satır karakteri ya da yanlış adlandırılmış bir HTTP üst bilgisi olduğunu buldum. HTTP trafiğine bakmadan bir web hizmetiyle ilgili programlama yapmak gözlerinizi kapatarak bir iğne iğnelemeye benzer.

Bununla birlikte, bir paket yoklayıcının kullanılamadığı veya şifrelenmiş paketleri yönetmek için yetersiz olduğu bir durumda kendinizi bulabilirsiniz. Program içi günlük kaydı mekanizmalarından yararlanarak bu sınırı aşmaktan asla korkmayın. Bu günlük kaydı mülklerini kullanarak şifrelenmiş HTTPS verileri veya uzaktan çalışan kod dahil olmak üzere değiş tokuş yapılan verilerin tümünü veya bir kısmını görebilirsiniz.

Bu makalede, Java, .NET ve Python için Google Data API istemci kitaplıklarını kullanarak 3 dilde örnek teşhis kodu yazdım. Her örnekte, günlük kaydını veya hata ayıklamayı açıyor, istemci girişini kullanarak kimlik doğrulaması yapıyor, ardından Google E-Tablolar listemi alıyor ve başlıklarını yazdırıyorum.

Java

İstemci kitaplığındaki birkaç temel nesne için günlük kaydı düzeylerini ayarlamak (ve sonuç olarak trafik verilerini açığa çıkarmak) için java.util.logging sınıflarını kullanabilirsiniz. Aşağıdaki örnekte, kablonun üzerinden geçenleri tam olarak görmek için HTTP üstbilgilerine ve XML ayrıştırıcının etkinliklerine bakmayı seçtim.

Google Veri Java istemci kitaplığı, HTTP isteklerini ve XML ayrıştırma işlemini işlemek için ayrı sınıflara sahiptir. Bu nedenle, her sınıf için bir tane olacak şekilde iki Loger nesnesi oluşturmam gerekir: com.google.gdata.client.http.HttpGDataRequest, XML ayrıştırma işleminden sorumluyken HTTP trafiğini işler.

Günlük kaydedici örnekleri, HttpGDataRequest ve XmlParser etkinliklerini kaydeder ve her bir günlük girişinin çıkışının ayrıntı düzeyini kontrol edebilirsiniz. Bu tanıtım için HttpGDataRequest ve XmlParser nesnelerinin oluşturduğu tüm etkinlikleri görüntülemeyi seçtim.

Günlükçilerimi oluşturup yapılandırdıktan sonra, sınıflarından bir etkinlik aldıklarında ne yapmaları gerektiğini onlara söylemem gerekiyor. Şimdilik tüm günlük kaydı bilgilerini konsola yazmak istiyorum. Bu yüzden bir ConsoleHandler oluşturdum ve her iki Logger'ıma da ekledim.

Örnek kodum:

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

Bu programı çalıştırdığınızda konsolda aşağıdakine benzer bir kod görürsünüz (Daha ilgi çekici olan kısımları çıkardım):

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

Bu günlükler oldukça büyük olabileceğinden, Günlükçü düzeylerini ayarlama konusunda daha seçici olmak isteyebilirsiniz. Günlük verilerini daha sonra kullanmak üzere depolayabilmeniz için ConsoleHandler yerine FileHandler da oluşturabilirsiniz.

Elbette Java size uygun değilse .NET'i deneyebilirsiniz.

.NET

.NET istemci kitaplığındaki HTTP trafiğini yakalamak için istemcideki varsayılan istek fabrikasını GDataLoggingRequestFactory ile değiştirebilirsiniz.

.NET kitaplığındaki HTTP istekleri, her bir Hizmet nesnesinin içindeki GDataRequestFactory tarafından oluşturulur. Normal istek fabrikaları herhangi bir günlük kaydı işlemi yapmaz ancak GDataRequestFactory ürününün bir alt sınıfı olan GDataLoggingRequestFactory, yerleşik günlük kaydına sahiptir. CombinedFileName ayarlayarak günlük dosyasının tam yolunu belirtebilirsiniz.

İsteğe bağlı fabrika kurulumunu yaptıktan sonra, hizmet nesnesinin RequestFactory değerini ayarlayarak Hizmet nesnenizdeki istek fabrikasını değiştirmeniz gerekir. Kodunuz aşağıdaki gibi görünebilir:

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

Açılan günlük dosyası XML isteklerini ve yanıtlarını içerir. tidy kullanarak biçimlendirdiğim kısaltılmış bir örneği burada bulabilirsiniz.

<?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>

Alfabeyi kullanmayı gerçekten seviyor ve Python kullanmayı tercih ediyorsunuz.

Python

Python istemci kitaplığında HTTP trafiğini yakalamak için HTTP istemcisinde hata ayıklama modunu etkinleştirerek HTTP üst bilgisi trafiğini konsola yansıtabilirsiniz. Hizmet nesnesinin, True olarak ayarlayabileceğiniz bir hata ayıklama üyesi vardır.

Hata ayıklamayı doğru değerine ayarlamak, hizmet nesnesinde bulunan temel HTTPRequest nesnesindeki hata ayıklama işaretini ayarlar.

Aşağıda, e-tablolarınızın listesini istediğinizde e-tablolar sunucusundan gönderilen HTTP başlıklarının yinelenmesini sağlayacak bir örnek verilmiştir.

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

Konsolunuzda buna benzer bir şey görürsünüz:

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

Ekleme veya güncelleme gibi ek işlemler yaparken, konsolunuza karşılık gelen istek verilerini görürsünüz.

Sonuç

Bu kısa eğiticide, Google Data API istemci kitaplıklarını kullanan Java, .NET veya Python programına temel günlük kaydı işlevini nasıl ekleyebileceğiniz gösterilmektedir. HTTP exchange'lerinde hata ayıklamanız gerekiyorsa ancak paket yoklayıcıya erişiminiz yoksa bu teknikler yararlı olabilir. Sadece bu örnekleri kullanarak bir yüzey çizdim. Bu dillerde bulunan günlük kaydı mekanizmalarının çoğu burada gösterilenden çok daha güçlüdür. Günlük kaydı veya Google Veri API'ları hakkında daha fazla bilgi edinmek isterseniz aşağıdaki kaynak listesine göz atabilirsiniz.

Bu makalede ele alınan istemci kitaplıkları şu sayfalarda bulunabilir:

İlgili bilgi tabanı öğeleri:

Tartışma grupları: Giderek daha fazla Google Veri API'si kullanıma sunuluyor. Grupları etkin bir şekilde izliyoruz.

Sorularınız veya önerileriniz varsa öğrenmekten memnuniyet duyarız. Tartışma grubuna katılın ve yayınlamaya başlayın.