You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by pq...@apache.org on 2010/01/06 00:42:22 UTC
svn commit: r896276 - in /incubator/libcloud/trunk/libcloud: __init__.py
base.py
Author: pquerna
Date: Tue Jan 5 23:42:21 2010
New Revision: 896276
URL: http://svn.apache.org/viewvc?rev=896276&view=rev
Log:
Add http tracing. To enable either set the enviroment variable LIBCLOUD_DEBUG to a file path or 1.
You can also enable it programtically by calling libcloud.enable_debug(file_like_object)
Modified:
incubator/libcloud/trunk/libcloud/__init__.py
incubator/libcloud/trunk/libcloud/base.py
Modified: incubator/libcloud/trunk/libcloud/__init__.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/libcloud/__init__.py?rev=896276&r1=896275&r2=896276&view=diff
==============================================================================
--- incubator/libcloud/trunk/libcloud/__init__.py (original)
+++ incubator/libcloud/trunk/libcloud/__init__.py Tue Jan 5 23:42:21 2010
@@ -19,4 +19,30 @@
@var __version__: Current version of libcloud
"""
-__version__ = "0.1.1-dev"
\ No newline at end of file
+__all__ = ["__version__", "enable_debug"]
+
+__version__ = "0.1.1-dev"
+
+
+def enable_debug(fo):
+ """
+ Enable library wide debugging to a file-like object.
+
+ @param fo: Where to append debugging information
+ @type fo: File like object, only write operations are used.
+ """
+ import httplib
+ from libcloud.base import ConnectionKey,LoggingHTTPSConnection
+ LoggingHTTPSConnection.log = fo
+ ConnectionKey.conn_classes = (httplib.HTTPConnection, LoggingHTTPSConnection)
+
+def _init_once():
+ import os
+ d = os.getenv("LIBCLOUD_DEBUG")
+ if d:
+ if d.isdigit():
+ d = "/tmp/libcloud_debug.log"
+ fo = open(d, "a")
+ enable_debug(fo)
+
+_init_once()
Modified: incubator/libcloud/trunk/libcloud/base.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/libcloud/base.py?rev=896276&r1=896275&r2=896276&view=diff
==============================================================================
--- incubator/libcloud/trunk/libcloud/base.py (original)
+++ incubator/libcloud/trunk/libcloud/base.py Tue Jan 5 23:42:21 2010
@@ -27,6 +27,7 @@
from libcloud.interface import INodeSizeFactory, INodeSize
from libcloud.interface import INodeImageFactory, INodeImage
import hashlib
+import StringIO
from pipes import quote as pquote
class Node(object):
@@ -192,33 +193,74 @@
#TODO: Move this to a better location/package
class LoggingHTTPSConnection(httplib.HTTPSConnection):
- """
- Debug class to log all HTTP(s) requests as they could be made
- with the C{curl} command.
-
- @cvar logfile: Path to logfile used to log curl commands
- """
- logfile = "/tmp/libcloud.log"
-
- def _to_curl(self, method, url, body, headers):
- cmd = ["curl", "--compressed"]
-
- cmd.extend(["-X", pquote(method)])
-
- for h in headers:
- cmd.extend(["-H", pquote("%s: %s" % (h, headers[h]))])
+ """
+ Debug class to log all HTTP(s) requests as they could be made
+ with the C{curl} command.
- if body is not None and len(body) > 0:
- cmd.extend(["--data-binary", pquote(body)])
-
- cmd.extend([pquote("https://%s:%d%s" % (self.host, self.port, url))])
- return " ".join(cmd)
+ @cvar log: file-like object that logs entries are written to.
+ """
+ log = None
- def request(self, method, url, body=None, headers=None):
- fp = open(self.logfile, 'a')
- fp.write(self._to_curl(method, url, body, headers) + "\n")
- fp.close()
- return httplib.HTTPSConnection.request(self, method, url, body, headers)
+ def _log_response(self, r):
+ rv = "# -------- begin %d response ----------\n" % (id(r))
+ ht = ""
+ v = r.version
+ if r.version == 10:
+ v = "HTTP/1.0"
+ if r.version == 11:
+ v = "HTTP/1.1"
+ ht += "%s %s %s\r\n" % (v, r.status, r.reason)
+ body = r.read()
+ for h in r.getheaders():
+ ht += "%s: %s\r\n" % (h[0].title(), h[1])
+ ht += "\r\n"
+ # this is evil. laugh with me. ha arharhrhahahaha
+ class fakesock:
+ def __init__(self, s):
+ self.s = s
+ def makefile(self, mode, foo):
+ return StringIO.StringIO(self.s)
+ rr = r
+ if r.chunked:
+ ht += "%x\r\n" % (len(body))
+ ht += body
+ ht += "\r\n0\r\n"
+ else:
+ ht += body
+ rr = httplib.HTTPResponse(fakesock(ht),
+ method=r._method,
+ debuglevel=r.debuglevel)
+ rr.begin()
+ rv += ht
+ rv += "# -------- end %d response ----------\n" % (id(r))
+ return (rr, rv)
+
+ def getresponse(self):
+ r = httplib.HTTPSConnection.getresponse(self)
+ if self.log is not None:
+ r, rv = self._log_response(r)
+ self.log.write(rv + "\n")
+ return r
+
+ def _log_curl(self, method, url, body, headers):
+ cmd = ["curl", "-i"]
+
+ cmd.extend(["-X", pquote(method)])
+
+ for h in headers:
+ cmd.extend(["-H", pquote("%s: %s" % (h, headers[h]))])
+
+ # TODO: in python 2.6, body can be a file-like object.
+ if body is not None and len(body) > 0:
+ cmd.extend(["--data-binary", pquote(body)])
+
+ cmd.extend([pquote("https://%s:%d%s" % (self.host, self.port, url))])
+ return " ".join(cmd)
+
+ def request(self, method, url, body=None, headers=None):
+ if self.log is not None:
+ self.log.write(self._log_curl(method, url, body, headers) + "\n")
+ return httplib.HTTPSConnection.request(self, method, url, body, headers)
class ConnectionKey(object):
"""