~launchpad-pqm/launchpad/devel

10303.1.1 by Gary Poster
use newest version of zc.buildout
1
# Copyright 2009 Canonical Ltd.  This software is licensed under the
2
# GNU Affero General Public License version 3 (see the file LICENSE).
3
4
# This file is imported by parts/scripts/sitecustomize.py, as set up in our
5
# buildout.cfg (see the "initialization" key in the "[scripts]" section).
6
12536.2.4 by Robert Collins
Fix branch a bit.
7
from collections import defaultdict
11594.2.1 by Aaron Bentley
Fix use of itertools.groupby through security proxies.
8
import itertools
14061.2.1 by Gavin Panella
Silence the amqplib logger globally, not just for scripts.
9
import logging
10303.1.1 by Gary Poster
use newest version of zc.buildout
10
import os
10981.1.1 by Maris Fogels
Silence DeprecationWarnings from pycrypto 2.0.1 using a new warnings hook in lp_sitecustomize.
11
import warnings
12
14061.2.1 by Gavin Panella
Silence the amqplib logger globally, not just for scripts.
13
from bzrlib.branch import Branch
11892.6.4 by Julian Edwards
Fix sourcepackagerecipebuild's handleStatus
14
from twisted.internet.defer import (
15
    Deferred,
16
    DeferredList,
17
    )
14061.2.1 by Gavin Panella
Silence the amqplib logger globally, not just for scripts.
18
from zope.interface import alsoProvides
19
import zope.publisher.browser
20
from zope.security import checker
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
21
14600.2.2 by Curtis Hovey
Moved webapp to lp.services.
22
from lp.services.webapp.interfaces import IUnloggedException
11300.2.49 by Stuart Bishop
Tidy and improve logging system infrastructure for great justice.
23
from lp.services.log import loglevels
8758.2.57 by Stuart Bishop
Move LaunchpadLogger to a better location
24
from lp.services.log.logger import LaunchpadLogger
11300.2.44 by Stuart Bishop
Tidy custom loglevels into their own module, and initialize filtering and custom levels in lp_sitecustomize.py for great justice.
25
from lp.services.log.mappingfilter import MappingFilter
11136.3.3 by Diogo Matsubara
move NullHandler to a more central location where it can be imported from lp_sitecustomize.py and test_layers.py test.
26
from lp.services.log.nullhandler import NullHandler
10303.1.1 by Gary Poster
use newest version of zc.buildout
27
from lp.services.mime import customizeMimetypes
10981.1.1 by Maris Fogels
Silence DeprecationWarnings from pycrypto 2.0.1 using a new warnings hook in lp_sitecustomize.
28
9590.1.95 by Michael Hudson
more comprehensive zope horror
29
11300.2.44 by Stuart Bishop
Tidy custom loglevels into their own module, and initialize filtering and custom levels in lp_sitecustomize.py for great justice.
30
def add_custom_loglevels():
31
    """Add out custom log levels to the Python logging package."""
11300.2.49 by Stuart Bishop
Tidy and improve logging system infrastructure for great justice.
32
33
    # This import installs custom ZODB loglevels, which we can then
34
    # override. BLATHER is between INFO and DEBUG, so we can leave it.
35
    # TRACE conflicts with DEBUG6, and since we are not using ZEO, we
36
    # just overwrite the level string by calling addLevelName.
37
    from ZODB.loglevels import BLATHER, TRACE
38
39
    # Confirm our above assumptions, and silence lint at the same time.
40
    assert BLATHER == 15
41
    assert TRACE == loglevels.DEBUG6
42
43
    logging.addLevelName(loglevels.DEBUG2, 'DEBUG2')
44
    logging.addLevelName(loglevels.DEBUG3, 'DEBUG3')
45
    logging.addLevelName(loglevels.DEBUG4, 'DEBUG4')
46
    logging.addLevelName(loglevels.DEBUG5, 'DEBUG5')
47
    logging.addLevelName(loglevels.DEBUG6, 'DEBUG6')
48
    logging.addLevelName(loglevels.DEBUG7, 'DEBUG7')
49
    logging.addLevelName(loglevels.DEBUG8, 'DEBUG8')
50
    logging.addLevelName(loglevels.DEBUG9, 'DEBUG9')
51
52
    # Install our customized Logger that provides easy access to our
53
    # custom loglevels.
8758.2.57 by Stuart Bishop
Move LaunchpadLogger to a better location
54
    logging.setLoggerClass(LaunchpadLogger)
11300.2.49 by Stuart Bishop
Tidy and improve logging system infrastructure for great justice.
55
9893.6.42 by Stuart Bishop
Override the root logger with an instance of LaunchpadLogger. Currently, code paths can fail when passed the root logger instead of a logger with our richer API.
56
    # Fix the root logger, replacing it with an instance of our
57
    # customized Logger. The original one is instantiated on import of
58
    # the logging module, so our override does not take effect without
59
    # this manual effort.
9893.6.45 by Stuart Bishop
Do more work replacing root logger, as bzrlib and zope have already created loggers on module import.
60
    old_root = logging.root
8758.2.57 by Stuart Bishop
Move LaunchpadLogger to a better location
61
    new_root = LaunchpadLogger('root', loglevels.WARNING)
9893.6.45 by Stuart Bishop
Do more work replacing root logger, as bzrlib and zope have already created loggers on module import.
62
63
    # Fix globals.
64
    logging.root = new_root
65
    logging.Logger.root = new_root
66
67
    # Fix manager.
68
    manager = logging.Logger.manager
69
    manager.root = new_root
70
71
    # Fix existing Logger instances.
72
    for logger in manager.loggerDict.values():
73
        if getattr(logger, 'parent', None) is old_root:
74
            logger.parent = new_root
9893.6.42 by Stuart Bishop
Override the root logger with an instance of LaunchpadLogger. Currently, code paths can fail when passed the root logger instead of a logger with our richer API.
75
11300.2.44 by Stuart Bishop
Tidy custom loglevels into their own module, and initialize filtering and custom levels in lp_sitecustomize.py for great justice.
76
14061.2.1 by Gavin Panella
Silence the amqplib logger globally, not just for scripts.
77
def silence_amqplib_logger():
78
    """Install the NullHandler on the amqplib logger to silence logs."""
79
    amqplib_logger = logging.getLogger('amqplib')
80
    amqplib_logger.addHandler(NullHandler())
81
    amqplib_logger.propagate = False
82
83
11136.3.7 by Diogo Matsubara
change the function name to reflect what it's doing
84
def silence_bzr_logger():
11136.3.6 by Diogo Matsubara
fix docstring
85
    """Install the NullHandler on the bzr logger to silence logs."""
12144.1.6 by Jonathan Lange
Don't let bzr log messages propagate
86
    bzr_logger = logging.getLogger('bzr')
87
    bzr_logger.addHandler(NullHandler())
88
    bzr_logger.propagate = False
11136.3.1 by Diogo Matsubara
silence the root logger across the entire Launchpad project
89
11300.2.49 by Stuart Bishop
Tidy and improve logging system infrastructure for great justice.
90
11300.2.44 by Stuart Bishop
Tidy custom loglevels into their own module, and initialize filtering and custom levels in lp_sitecustomize.py for great justice.
91
def silence_zcml_logger():
92
    """Lower level of ZCML parsing DEBUG messages."""
93
    config_filter = MappingFilter(
94
        {logging.DEBUG: (7, 'DEBUG4')}, 'config')
95
    logging.getLogger('config').addFilter(config_filter)
96
11300.2.49 by Stuart Bishop
Tidy and improve logging system infrastructure for great justice.
97
11300.2.44 by Stuart Bishop
Tidy custom loglevels into their own module, and initialize filtering and custom levels in lp_sitecustomize.py for great justice.
98
def silence_transaction_logger():
99
    """Lower level of DEBUG messages from the transaction module."""
100
    # Transaction logging is too noisy. Lower its DEBUG messages
101
    # to DEBUG3. Transactions log to loggers named txn.<thread_id>,
102
    # so we need to register a null handler with a filter to ensure
103
    # the logging records get mutated before being propagated up
104
    # to higher level loggers.
105
    txn_handler = NullHandler()
106
    txn_filter = MappingFilter(
107
        {logging.DEBUG: (8, 'DEBUG3')}, 'txn')
108
    txn_handler.addFilter(txn_filter)
109
    logging.getLogger('txn').addHandler(txn_handler)
110
11300.2.49 by Stuart Bishop
Tidy and improve logging system infrastructure for great justice.
111
9590.1.95 by Michael Hudson
more comprehensive zope horror
112
def dont_wrap_class_and_subclasses(cls):
113
    checker.BasicTypes.update({cls: checker.NoProxy})
114
    for subcls in cls.__subclasses__():
115
        dont_wrap_class_and_subclasses(subcls)
10303.1.1 by Gary Poster
use newest version of zc.buildout
116
11300.2.49 by Stuart Bishop
Tidy and improve logging system infrastructure for great justice.
117
10981.1.1 by Maris Fogels
Silence DeprecationWarnings from pycrypto 2.0.1 using a new warnings hook in lp_sitecustomize.
118
def silence_warnings():
119
    """Silence warnings across the entire Launchpad project."""
120
    # pycrypto-2.0.1 on Python2.6:
121
    #   DeprecationWarning: the sha module is deprecated; use the hashlib
122
    #   module instead
123
    warnings.filterwarnings(
124
        "ignore",
125
        category=DeprecationWarning,
126
        module="Crypto")
12398.2.16 by Jonathan Lange
Respond to review comments
127
    # Filter all deprecation warnings for Zope 3.6, which emanate from
12398.2.9 by Jonathan Lange
Better docstring.
128
    # the zope package.
129
    filter_pattern = '.*(Zope 3.6|provide.*global site manager).*'
130
    warnings.filterwarnings(
131
        'ignore', filter_pattern, category=DeprecationWarning)
132
    # XXX wgrant 2010-03-30 bug=551510:
133
    # Also filter apt_pkg warnings, since Lucid's python-apt has a new API.
134
    warnings.filterwarnings(
135
        'ignore', '.*apt_pkg.*', category=DeprecationWarning)
10981.1.1 by Maris Fogels
Silence DeprecationWarnings from pycrypto 2.0.1 using a new warnings hook in lp_sitecustomize.
136
11300.2.49 by Stuart Bishop
Tidy and improve logging system infrastructure for great justice.
137
9893.6.28 by Stuart Bishop
Reset logging between tests to Launchpad default state, not Z3 default state
138
def customize_logger():
139
    """Customize the logging system.
140
141
    This function is also invoked by the test infrastructure to reset
142
    logging between tests.
143
    """
14061.2.1 by Gavin Panella
Silence the amqplib logger globally, not just for scripts.
144
    silence_amqplib_logger()
9893.6.28 by Stuart Bishop
Reset logging between tests to Launchpad default state, not Z3 default state
145
    silence_bzr_logger()
146
    silence_zcml_logger()
147
    silence_transaction_logger()
148
149
13225.9.1 by Benji York
add the ability to mark an exception as not OOPS report worthy and use
150
def customize_get_converter(zope_publisher_browser=zope.publisher.browser):
151
    """URL parameter conversion errors shouldn't generate an OOPS report.
152
153
    This injects (monkey patches) our wrapper around get_converter so improper
154
    use of parameter type converters (like http://...?foo=bar:int) won't
155
    generate OOPS reports.
156
    """
157
    original_get_converter = zope_publisher_browser.get_converter
158
159
    def get_converter(*args, **kws):
160
        """Get a type converter but turn off OOPS reporting if it fails."""
161
        converter = original_get_converter(*args, **kws)
162
163
        def wrapped_converter(v):
164
            try:
165
                return converter(v)
166
            except ValueError, e:
167
                # Mark the exception as not being OOPS-worthy.
168
                alsoProvides(e, IUnloggedException)
169
                raise
170
13225.9.3 by Benji York
add support for get_converter returning None
171
        # The converter can be None, in which case wrapping it makes no sense,
172
        # otherwise it is a function which we wrap.
173
        if converter is None:
174
            return None
175
        else:
176
            return wrapped_converter
13225.9.1 by Benji York
add the ability to mark an exception as not OOPS report worthy and use
177
178
    zope_publisher_browser.get_converter = get_converter
179
180
11692.4.1 by Gary Poster
Allow .lpconfig to be honored if initial configuration is "development"
181
def main(instance_name):
182
    # This is called by our custom buildout-generated sitecustomize.py
183
    # in parts/scripts/sitecustomize.py. The instance name is sent to
184
    # buildout from the Makefile, and then inserted into
185
    # sitecustomize.py.  See buildout.cfg in the "initialization" value
186
    # of the [scripts] section for the code that goes into this custom
187
    # sitecustomize.py.  We do all actual initialization here, in a more
188
    # visible place.
189
    if instance_name and instance_name != 'development':
190
        # See bug 656213 for why we do this carefully.
191
        os.environ.setdefault('LPCONFIG', instance_name)
10303.1.1 by Gary Poster
use newest version of zc.buildout
192
    os.environ['STORM_CEXTENSIONS'] = '1'
11300.2.44 by Stuart Bishop
Tidy custom loglevels into their own module, and initialize filtering and custom levels in lp_sitecustomize.py for great justice.
193
    add_custom_loglevels()
10303.1.1 by Gary Poster
use newest version of zc.buildout
194
    customizeMimetypes()
9590.1.95 by Michael Hudson
more comprehensive zope horror
195
    dont_wrap_class_and_subclasses(Branch)
12536.2.4 by Robert Collins
Fix branch a bit.
196
    checker.BasicTypes.update({defaultdict: checker.NoProxy})
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
197
    checker.BasicTypes.update({Deferred: checker.NoProxy})
11892.6.4 by Julian Edwards
Fix sourcepackagerecipebuild's handleStatus
198
    checker.BasicTypes.update({DeferredList: checker.NoProxy})
11594.2.1 by Aaron Bentley
Fix use of itertools.groupby through security proxies.
199
    checker.BasicTypes[itertools.groupby] = checker._iteratorChecker
11594.2.2 by Aaron Bentley
Handle itertools._grouper as well.
200
    # The itertools._grouper type is not exposed by name, so we must get it
201
    # through actually using itertools.groupby.
202
    grouper = type(list(itertools.groupby([0]))[0][1])
203
    checker.BasicTypes[grouper] = checker._iteratorChecker
10981.1.1 by Maris Fogels
Silence DeprecationWarnings from pycrypto 2.0.1 using a new warnings hook in lp_sitecustomize.
204
    silence_warnings()
9893.6.28 by Stuart Bishop
Reset logging between tests to Launchpad default state, not Z3 default state
205
    customize_logger()
13225.9.1 by Benji York
add the ability to mark an exception as not OOPS report worthy and use
206
    customize_get_converter()