Revision e820685c
b/lib/http.py | ||
---|---|---|
150 | 150 |
code = 505 |
151 | 151 |
|
152 | 152 |
|
153 |
class ApacheLogfile: |
|
154 |
"""Utility class to write HTTP server log files. |
|
155 |
|
|
156 |
The written format is the "Common Log Format" as defined by Apache: |
|
157 |
http://httpd.apache.org/docs/2.2/mod/mod_log_config.html#examples |
|
158 |
|
|
159 |
""" |
|
160 |
def __init__(self, fd): |
|
161 |
"""Constructor for ApacheLogfile class. |
|
162 |
|
|
163 |
Args: |
|
164 |
- fd: Open file object |
|
165 |
|
|
166 |
""" |
|
167 |
self._fd = fd |
|
168 |
|
|
169 |
def LogRequest(self, request, format, *args): |
|
170 |
self._fd.write("%s %s %s [%s] %s\n" % ( |
|
171 |
# Remote host address |
|
172 |
request.address_string(), |
|
173 |
|
|
174 |
# RFC1413 identity (identd) |
|
175 |
"-", |
|
176 |
|
|
177 |
# Remote user |
|
178 |
"-", |
|
179 |
|
|
180 |
# Request time |
|
181 |
self._FormatCurrentTime(), |
|
182 |
|
|
183 |
# Message |
|
184 |
format % args, |
|
185 |
)) |
|
186 |
self._fd.flush() |
|
187 |
|
|
188 |
def _FormatCurrentTime(self): |
|
189 |
"""Formats current time in Common Log Format. |
|
190 |
|
|
191 |
""" |
|
192 |
return self._FormatLogTime(time.time()) |
|
193 |
|
|
194 |
def _FormatLogTime(self, seconds): |
|
195 |
"""Formats time for Common Log Format. |
|
196 |
|
|
197 |
All timestamps are logged in the UTC timezone. |
|
198 |
|
|
199 |
Args: |
|
200 |
- seconds: Time in seconds since the epoch |
|
201 |
|
|
202 |
""" |
|
203 |
(_, month, _, _, _, _, _, _, _) = tm = time.gmtime(seconds) |
|
204 |
format = "%d/" + MONTHNAME[month] + "/%Y:%H:%M:%S +0000" |
|
205 |
return time.strftime(format, tm) |
|
206 |
|
|
207 |
|
|
208 | 153 |
class HTTPJsonConverter: |
209 | 154 |
CONTENT_TYPE = "application/json" |
210 | 155 |
|
b/test/ganeti.http_unittest.py | ||
---|---|---|
30 | 30 |
from ganeti import http |
31 | 31 |
|
32 | 32 |
|
33 |
class HttpLogfileTests(unittest.TestCase): |
|
34 |
"""Tests for ApacheLogfile class.""" |
|
35 |
|
|
36 |
class FakeRequest: |
|
37 |
FAKE_ADDRESS = "1.2.3.4" |
|
38 |
|
|
39 |
def address_string(self): |
|
40 |
return self.FAKE_ADDRESS |
|
41 |
|
|
42 |
def setUp(self): |
|
43 |
self.tmpfile = tempfile.NamedTemporaryFile() |
|
44 |
self.logfile = http.ApacheLogfile(self.tmpfile) |
|
45 |
|
|
46 |
def tearDown(self): |
|
47 |
self.tmpfile.close() |
|
48 |
|
|
49 |
def testFormatLogTime(self): |
|
50 |
self._TestInTimezone(1208646123.0, "Europe/London", |
|
51 |
"19/Apr/2008:23:02:03 +0000") |
|
52 |
self._TestInTimezone(1208646123, "Europe/Zurich", |
|
53 |
"19/Apr/2008:23:02:03 +0000") |
|
54 |
self._TestInTimezone(1208646123, "Australia/Sydney", |
|
55 |
"19/Apr/2008:23:02:03 +0000") |
|
56 |
|
|
57 |
def _TestInTimezone(self, seconds, timezone, expected): |
|
58 |
"""Tests HttpLogfile._FormatLogTime with a specific timezone |
|
59 |
|
|
60 |
""" |
|
61 |
# Preserve environment |
|
62 |
old_TZ = os.environ.get("TZ", None) |
|
63 |
try: |
|
64 |
os.environ["TZ"] = timezone |
|
65 |
time.tzset() |
|
66 |
result = self.logfile._FormatLogTime(seconds) |
|
67 |
finally: |
|
68 |
# Restore environment |
|
69 |
if old_TZ is not None: |
|
70 |
os.environ["TZ"] = old_TZ |
|
71 |
elif "TZ" in os.environ: |
|
72 |
del os.environ["TZ"] |
|
73 |
time.tzset() |
|
74 |
|
|
75 |
self.assertEqual(result, expected) |
|
76 |
|
|
77 |
|
|
78 |
def testLogRequest(self): |
|
79 |
request = self.FakeRequest() |
|
80 |
self.logfile.LogRequest(request, "This is only a %s", "test") |
|
33 |
# TODO: Write unittests |
|
81 | 34 |
|
82 | 35 |
|
83 | 36 |
if __name__ == '__main__': |
Also available in: Unified diff