[Zope-Checkins] CVS: Zope/lib/python/Products/SiteErrorLog - SiteErrorLog.py:1.1.2.1 __init__.py:1.1.2.1

Shane Hathaway shane@cvs.zope.org
Tue, 2 Apr 2002 18:10:16 -0500


Update of /cvs-repository/Zope/lib/python/Products/SiteErrorLog
In directory cvs.zope.org:/tmp/cvs-serv1083

Added Files:
      Tag: shane-better-tracebacks-branch
	SiteErrorLog.py __init__.py 
Log Message:
Added SiteErrorLog product.


=== Added File Zope/lib/python/Products/SiteErrorLog/SiteErrorLog.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
# 
##############################################################################
"""Site error log module.

$Id: SiteErrorLog.py,v 1.1.2.1 2002/04/02 23:10:13 shane Exp $
"""

import os
import sys
from thread import allocate_lock
from types import StringType, UnicodeType

import Globals
from Acquisition import aq_base
from AccessControl import ClassSecurityInfo, getSecurityManager, Unauthorized
from OFS.SimpleItem import SimpleItem
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
from zExceptions.ExceptionFormatter import format_exception
from zLOG import LOG, ERROR

use_error_logging = 'Log Site Errors'
log_to_event_log = 'Log to the Event Log'


_www = os.path.join(os.path.dirname(__file__), 'www')

# temp_logs holds the logs.
temp_logs = {}  # { oid -> [ traceback string ] }

cleanup_lock = allocate_lock()


class SiteErrorLog (SimpleItem):
    """Site error log class.  You can put an error log anywhere in the tree
    and exceptions in that area will be posted to the site error log.
    """
    meta_type = 'Site Error Log'
    id = 'error_log'

    keep_entries = 10
    copy_to_zlog = 0

    security = ClassSecurityInfo()

    manage_options = (
        {'label': 'Log', 'action': 'manage_main'},
        ) + SimpleItem.manage_options

    security.declareProtected(use_error_logging, 'getProperties')
    manage_main = PageTemplateFile('main.pt', _www)

    security.declarePrivate('manage_beforeDelete')
    def manage_beforeDelete(self, item, container):
        if item is self:
            try:
                del container.__error_log__
            except AttributeError:
                pass

    security.declarePrivate('manage_afterAdd')
    def manage_afterAdd(self, item, container):
        if item is self:
            container.__error_log__ = aq_base(self)

    def _setId(self, id):
        if id != self.id:
            raise Globals.MessageDialog(
                title='Invalid Id',
                message='Cannot change the id of a SiteErrorLog',
                action ='./manage_main',)

    def _getLog(self):
        """Returns the log for this object.

        Careful, the log is shared between threads.
        """
        log = temp_logs.get(self._p_oid, None)
        if log is None:
            log = []
            temp_logs[self._p_oid] = log
        return log

    security.declarePrivate('raising')
    def raising(self, info):
        """Log an exception.

        Called by SimpleItem's exception handler.
        """
        try:
            try:
                tb_text = None
                tb_html = None

                if not isinstance(info[2], StringType) and not isinstance(
                    info[2], UnicodeType):
                    tb_text = format_exception(*info, **{'as_html': 0})
                    tb_html = format_exception(*info, **{'as_html': 1})
                else:
                    tb_text = info[2]

                request = getattr(self, 'REQUEST', None)
                url = None
                if request:
                    url = request['URL']

                log = self._getLog()
                log.append({
                    'tb_text': tb_text,
                    'tb_html': tb_html,
                    'url': url,
                    })

                cleanup_lock.acquire()
                try:
                    if len(log) >= self.keep_entries:
                        del log[:-keep_entries]
                finally:
                    cleanup_lock.release()
            except:
                LOG('SiteError', ERROR, 'Error while logging',
                    error=sys.exc_info())
            else:
                if self.copy_to_zlog:
                    LOG('SiteError', ERROR, str(url), error=info)
        finally:
            info = None

    security.declareProtected(use_error_logging, 'getProperties')
    def getProperties(self):
        return {'keep_entries': self.keep_entries,
                'copy_to_zlog': self.copy_to_zlog}

    security.declarePublic('checkEventLogPermission')
    def checkEventLogPermission(self):
        if not getSecurityManager().checkPermission(log_to_event_log, self):
            raise Unauthorized, ('You do not have the "%s" permission.' %
                                 log_to_event_log)
        return 1

    security.declareProtected(use_error_logging, 'setProperties')
    def setProperties(self, keep_entries, copy_to_zlog=0, RESPONSE=None):
        """Sets the properties of this site error log.
        """
        self.keep_entries = int(keep_entries)
        copy_to_zlog = not not copy_to_zlog
        if copy_to_zlog and not self.copy_to_zlog:
            # Before turning on event logging, check the permission.
            self.checkEventLogPermission()
        self.copy_to_zlog = copy_to_zlog
        if RESPONSE is not None:
            RESPONSE.redirect(
                '%s/manage_main?manage_tabs_message=Changed+properties.' %
                self.absolute_url())
    
    

Globals.InitializeClass(SiteErrorLog)


def manage_addErrorLog(dispatcher, RESPONSE=None):
    """Add a site error log to a container."""
    log = SiteErrorLog()
    dispatcher._setObject(log.id, log)
    if RESPONSE is not None:
        RESPONSE.redirect(
            dispatcher.DestinationURL() +
            '/manage_main?manage_tabs_message=Error+Log+Added.' )



=== Added File Zope/lib/python/Products/SiteErrorLog/__init__.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
# 
##############################################################################
"""Site error log product.

$Id: __init__.py,v 1.1.2.1 2002/04/02 23:10:13 shane Exp $
"""

import SiteErrorLog

def initialize(context):
    context.registerClass(SiteErrorLog.SiteErrorLog,
                          constructors=(SiteErrorLog.manage_addErrorLog,),
                          permission=SiteErrorLog.use_error_logging,
                          icon='www/error.gif')