Google डेटा एपीआई क्लाइंट को डीबग करना: अपने प्रोग्राम में ट्रैफ़िक की खोज करना

जेफ़्री स्कॉडर, Google डेटा एपीआई टीम
जून 2007

सुविधा के बारे में जानकारी

कभी-कभी यह देखने का कोई विकल्प नहीं होता कि तार में क्या चलता है. यह तरीका खास तौर पर तब लागू होता है, जब Google Data API जैसी वेब सेवाओं का इस्तेमाल करने वाला कोई सॉफ़्टवेयर लिखा जाता है. इनमें कई कार्रवाइयों में एचटीटीपी अनुरोध करना शामिल है. सब कुछ विफल होने पर, आप यह पुष्टि कर सकते हैं कि आपका प्रोग्राम वही काम कर रहा है या नहीं, जो आप असल में ट्रांसमिट की गई और मिली बाइट देखकर करेंगे. 'Google डेटा एपीआई' की कई क्लाइंट लाइब्रेरी में डीबग करने का मोड होता है जो एचटीटीपी ट्रैफ़िक दिखाता है. यह खास तौर पर तब काम आता है, जब आपके पास Wire शार्क या फ़िडलर जैसे पैकेट स्निफ़र का ऐक्सेस न हो.

मैं यह नहीं बता सकता कि मेरा कार्यक्रम सही तरीके से कितनी बार लागू हुआ है. ऐसा सिर्फ़ एक पैकेट ट्रेस की जांच करने के लिए किया जा सकता है जिसमें कोई अतिरिक्त न्यूलाइन वर्ण या गलत नाम वाला एचटीटीपी हेडर होता है. एचटीटीपी ट्रैफ़िक को देखे बिना किसी वेब सेवा के लिए प्रोग्रामिंग करना, अपनी आंखों को ग्लूक करके दिखाने की कोशिश करने जैसा है.

हालांकि, आपको ऐसी स्थिति में मिल सकता है जहां पैकेट स्निफ़र उपलब्ध न हो या जो एन्क्रिप्ट किए गए पैकेट से निपटने के लिए काफ़ी न हो. डरें नहीं, प्रोग्राम में लॉग इन करने के कुछ तरीकों का इस्तेमाल करके, आप यह समस्या हल कर सकते हैं. डेटा इकट्ठा करने की इन सुविधाओं का इस्तेमाल करके, कुछ डेटा को बदला जा सकता है. हालांकि, यह डेटा एन्क्रिप्ट (सुरक्षित) किए गए एचटीटीपीएस डेटा या रिमोट रनिंग कोड के लिए भी देखा जा सकता है.

इस लेख के लिए, मैंने Java, .NET, और Python के लिए Google डेटा एपीआई क्लाइंट लाइब्रेरी का इस्तेमाल करके, तीन भाषाओं में सैंपल डाइग्नोस्टिक्स कोड लिखा है. हर उदाहरण में, मैं लॉग इन या डीबग करने की सुविधा चालू करता/करती हूं, क्लाइंट लॉगिन का इस्तेमाल करके पुष्टि करता/करती हूं. इसके बाद, मुझे अपनी 'Google स्प्रेडशीट' की सूची मिलती है और उनके शीर्षक प्रिंट कर लिए जाते हैं.

Java

क्लाइंट लाइब्रेरी में कुछ मुख्य ऑब्जेक्ट के लिए, लॉगिंग लेवल सेट करने और ट्रैफ़िक डेटा को सार्वजनिक करने के लिए, java.util.logging क्लास का इस्तेमाल किया जा सकता है. नीचे दिए गए उदाहरण में, मैंने एचटीटीपी हेडर और एक्सएमएल पार्सर की गतिविधियों को देखने का विकल्प चुना है. इससे, यह जानकारी देखी जा सकती है कि वायर पर क्या हो रहा है.

Google Data Java क्लाइंट लाइब्रेरी में एचटीटीपी अनुरोध और एक्सएमएल पार्सिंग मैनेज करने के लिए अलग-अलग क्लास होती हैं. इस तरह, मुझे दो लॉगर ऑब्जेक्ट बनाने होते हैं, हर क्लास के लिए एक: com.google.gdata.client.http.HttpGDataRequest एचटीटीपी ट्रैफ़िक को हैंडल करता है, जबकि एक्सएमएल पार्सिंग के लिए com.google.gdata.util.XmlParser ज़िम्मेदार होता है.

लॉगर इंस्टेंस 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

ये लॉग बहुत बड़े हो सकते हैं, इसलिए हो सकता है कि आप लॉगर के स्तर सेट करने के लिए ज़्यादा चुनिंदा होना चाहें. आपके पास ConsoleHandler का इस्तेमाल करके FileHandler को बनाने का विकल्प भी है, ताकि आप लॉग डेटा को बाद में इस्तेमाल करने के लिए सेव कर सकें.

बेशक, अगर Java आपका बैग नहीं है, तो आप .NET आज़मा सकते हैं.

.NET

.NET क्लाइंट लाइब्रेरी में एचटीटीपी ट्रैफ़िक को कैप्चर करने के लिए, क्लाइंट में डिफ़ॉल्ट अनुरोध फ़ैक्ट्री को GDataLoggingRequestFactory से बदला जा सकता है.

.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 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 क्लाइंट लाइब्रेरी में एचटीटीपी ट्रैफ़िक को कैप्चर करने के लिए, आप एचटीटीपी क्लाइंट ट्रैफ़िक में डीबग मोड चालू करके, कंसोल पर एचटीटीपी हेडर ट्रैफ़िक को इको कर सकते हैं. सेवा ऑब्जेक्ट में एक डीबग सदस्य है, जिसे आप सही पर सेट कर सकते हैं.

डीबग को 'सही' पर सेट करने पर, दिए गए 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 क्लाइंट लाइब्रेरी का इस्तेमाल करती है. ये तकनीक तब काम आ सकती हैं, जब आपको एचटीटीपी एक्सचेंज को डीबग करने की ज़रूरत हो, लेकिन आपके पास पैकेट स्निफ़र का ऐक्सेस न हो. मैंने सिर्फ़ इन उदाहरणों से सतह को स्क्रैच किया है. इस भाषा में लॉग इन करने के कई तरीके, यहां दिखाए गए तरीके से ज़्यादा कारगर हैं. अगर आपको लॉगिंग या Google डेटा एपीआई के बारे में ज़्यादा जानकारी चाहिए, तो इन संसाधनों की सूची देखें.

इस लेख में शामिल क्लाइंट लाइब्रेरी, इन पेजों पर देखी जा सकती हैं:

इससे जुड़े नॉलेज बेस आइटम:

बातचीत के लिए ग्रुप: हमारे पास कुछ ही हैं. ज़्यादा Google Data API लॉन्च होने जा रहा है. हम उन ग्रुप पर लगातार नज़र रखते हैं.

अगर आपके पास कोई सवाल या सुझाव है, तो हमें बताएं. चर्चा समूह पर जाएं और पोस्ट करना शुरू करें.