[Zope3-checkins] SVN: Zope3/branches/srichter-twisted-integration/src/zope/app/server/ Reimplemented common access log using Twisted's log framework. It uses our

Stephan Richter srichter at cosmos.phy.tufts.edu
Wed Apr 20 16:57:53 EDT 2005


Log message for revision 30066:
  Reimplemented common access log using Twisted's log framework. It uses our 
  setup accesslog. Tests will follow, but BjornT wants to have a look.
  
  

Changed:
  A   Zope3/branches/srichter-twisted-integration/src/zope/app/server/log.py
  U   Zope3/branches/srichter-twisted-integration/src/zope/app/server/main.py
  U   Zope3/branches/srichter-twisted-integration/src/zope/app/server/server.py

-=-
Added: Zope3/branches/srichter-twisted-integration/src/zope/app/server/log.py
===================================================================
--- Zope3/branches/srichter-twisted-integration/src/zope/app/server/log.py	2005-04-20 19:55:14 UTC (rev 30065)
+++ Zope3/branches/srichter-twisted-integration/src/zope/app/server/log.py	2005-04-20 20:57:53 UTC (rev 30066)
@@ -0,0 +1,121 @@
+##############################################################################
+#
+# Copyright (c) 2005 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Logging Support
+
+Logging Support for the Twisted logging framework. A special observer will
+forward messages to the standard Python Logging Framework. 
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+import logging
+import time
+import twisted.python.log
+from twisted import web2
+from zope.interface import implements
+from zope.app.http.httpdate import monthname
+
+
+class CommonAccessLoggingObserver(object):
+    """Outputs accesses in common HTTP log format."""
+
+    def __init__(self, logger=None):
+        if logger is None:
+            logger = logging.getLogger('accesslog')
+        self.logger = logger
+
+    def computeTimezoneForLog(self, tz):
+        if tz > 0:
+            neg = 1
+        else:
+            neg = 0
+            tz = -tz
+        h, rem = divmod (tz, 3600)
+        m, rem = divmod (rem, 60)
+        if neg:
+            return '-%02d%02d' % (h, m)
+        else:
+            return '+%02d%02d' % (h, m)
+
+    tzForLog = None
+    tzForLogAlt = None
+
+    def logDateString(self, when):
+        logtime = time.localtime(when)
+        Y, M, D, h, m, s = logtime[:6]
+        
+        if not time.daylight:
+            tz = self.tzForLog
+            if tz is None:
+                tz = self.computeTimezoneForLog(time.timezone)
+                self.tzForLog = tz
+        else:
+            tz = self.tzForLogAlt
+            if tz is None:
+                tz = self.computeTimezoneForLog(time.altzone)
+                self.tzForLogAlt = tz
+
+        return '%d/%s/%02d:%02d:%02d:%02d %s' % (
+            D, monthname[M], Y, h, m, s, tz)
+
+    def emit(self, eventDict):
+        """See zope.app.logger.interfaces.IPublisherRequestLogger"""
+        if eventDict.get('interface') is not web2.iweb.IRequest:
+            return
+
+        request = eventDict['request']
+
+        firstLine = '%s %s HTTP/%s' %(
+            request.method,
+            request.uri,
+            '.'.join([str(x) for x in request.clientproto]))
+
+        self.logger.log(logging.INFO,
+            '%s - %s [%s] "%s" %s %d "%s" "%s"' %(
+                request.chanRequest.transport.client[0],
+                request.response.headers.getRawHeaders(
+                    'x-zope-principal', ['anonymous'])[-1],
+                self.logDateString(response.headers.getHeader('date', 0)),
+                firstLine,
+                request.response.code,
+                request.bytesSent,
+                request.headers.getHeader('referer', '-'),
+                request.headers.getHeader('user-agent', '-')
+                )
+            )
+
+    def start(self):
+        """Start observing log events."""
+        twisted.python.log.addObserver(self.emit)
+
+    def stop(self):
+        """Stop observing log events."""
+        twisted.python.log.removeObserver(self.emit)
+
+
+
+class CommonFTPActivityLoggingObserver(CommonAccessLoggingObserver):
+    """Outputs hits in common HTTP log format."""
+
+    def log(self, request):
+        """See zope.app.logger.interfaces.IPublisherRequestLogger"""
+        now = time.time()
+        message = ' - %s [%s] "%s %s"' % (task.channel.username,
+                                       self.log_date_string(now),
+                                       task.m_name[4:].upper(),
+                                       task.channel.cwd,
+                                       )
+
+        self.output.logRequest(task.channel.addr[0], message)


Property changes on: Zope3/branches/srichter-twisted-integration/src/zope/app/server/log.py
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: Zope3/branches/srichter-twisted-integration/src/zope/app/server/main.py
===================================================================
--- Zope3/branches/srichter-twisted-integration/src/zope/app/server/main.py	2005-04-20 19:55:14 UTC (rev 30065)
+++ Zope3/branches/srichter-twisted-integration/src/zope/app/server/main.py	2005-04-20 20:57:53 UTC (rev 30066)
@@ -32,6 +32,7 @@
 import zope.app.appsetup
 import zope.app.appsetup.interfaces
 from zope.app import wsgi
+from zope.app.server import log
 
 CONFIG_FILENAME = "zope.conf"
 
@@ -105,6 +106,10 @@
     options.eventlog()
     options.accesslog()
 
+    # Setup the logs. Eventually this might be better done using utilities.
+    observer = log.CommonAccessLoggingObserver()
+    observer.start()
+
     zope.app.appsetup.config(options.site_definition)
 
     db = options.database.open()

Modified: Zope3/branches/srichter-twisted-integration/src/zope/app/server/server.py
===================================================================
--- Zope3/branches/srichter-twisted-integration/src/zope/app/server/server.py	2005-04-20 19:55:14 UTC (rev 30065)
+++ Zope3/branches/srichter-twisted-integration/src/zope/app/server/server.py	2005-04-20 20:57:53 UTC (rev 30066)
@@ -19,13 +19,13 @@
 """
 import logging
 
+from twisted.application import internet
+from twisted.internet import reactor, interfaces
+
 from zope.interface import implements
 from zope.app import zapi
 from zope.app.server.interfaces import IServerType, ISSLServerType
 
-from twisted.application import internet
-from twisted.internet import reactor, interfaces
-
 class SSLNotSupported(Exception):
     ''' '''
 



More information about the Zope3-Checkins mailing list