~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/log.py

(jameinel) Allow 'bzr serve' to interpret SIGHUP as a graceful shutdown.
 (bug #795025) (John A Meinel)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007 Canonical Ltd
 
1
# Copyright (C) 2008, 2009, 2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
"""Transport decorator that logs transport operations to .bzr.log."""
18
18
 
26
26
import types
27
27
 
28
28
from bzrlib.trace import mutter
29
 
from bzrlib.transport.decorator import (
30
 
    TransportDecorator,
31
 
    )
32
 
from bzrlib.transport.trace import (
33
 
    DecoratorServer,
34
 
    TransportTraceDecorator,
35
 
    )
36
 
 
37
 
 
38
 
 
39
 
 
40
 
class TransportLogDecorator(TransportDecorator):
 
29
from bzrlib.transport import decorator
 
30
 
 
31
 
 
32
class TransportLogDecorator(decorator.TransportDecorator):
41
33
    """Decorator for Transports that logs interesting operations to .bzr.log.
42
34
 
43
35
    In general we want to log things that usually take a network round trip
44
36
    and may be slow.
45
37
 
46
38
    Not all operations are logged yet.
 
39
 
 
40
    See also TransportTraceDecorator, that records a machine-readable log in 
 
41
    memory for eg testing.
47
42
    """
48
43
 
49
44
    def __init__(self, *args, **kw):
104
99
    def _show_result(self, before, methodname, result):
105
100
        result_len = None
106
101
        if isinstance(result, types.GeneratorType):
107
 
            # eagerly pull in all the contents, so that we can measure how
108
 
            # long it takes to get them.  this does make the behaviour a bit
109
 
            # different, but we hope not noticably so
 
102
            # We now consume everything from the generator so that we can show
 
103
            # the results and the time it took to get them.  However, to keep
 
104
            # compatibility with callers that may specifically expect a result
 
105
            # (see <https://launchpad.net/bugs/340347>) we also return a new
 
106
            # generator, reset to the starting position.
110
107
            result = list(result)
 
108
            return_result = iter(result)
 
109
        else:
 
110
            return_result = result
111
111
        if isinstance(result, (cStringIO.OutputType, StringIO.StringIO)):
112
112
            val = repr(result.getvalue())
113
113
            result_len = len(val)
122
122
        else:
123
123
            shown_result = self._shorten(self._strip_tuple_parens(result))
124
124
        mutter("  --> %s" % shown_result)
125
 
        # XXX: the time may be wrong when e.g. a generator object is returned from
126
 
        # an http readv, if the object is returned before the bulk data
127
 
        # is read.
128
 
        elapsed = time.time() - before
129
 
        if result_len and elapsed > 0:
130
 
            # this is the rate of higher-level data, not the raw network speed
131
 
            mutter("      %9.03fs %8dkB/s" % (elapsed, result_len/elapsed/1024))
132
 
        else:
133
 
            mutter("      %9.03fs" % (elapsed))
134
 
        return result
 
125
        # The log decorator no longer shows the elapsed time or transfer rate
 
126
        # because they're available in the log prefixes and the transport
 
127
        # activity display respectively.
 
128
        if False:
 
129
            elapsed = time.time() - before
 
130
            if result_len and elapsed > 0:
 
131
                # this is the rate of higher-level data, not the raw network
 
132
                # speed using base-10 units (see HACKING.txt).
 
133
                mutter("      %9.03fs %8dkB/s"
 
134
                       % (elapsed, result_len/elapsed/1000))
 
135
            else:
 
136
                mutter("      %9.03fs" % (elapsed))
 
137
        return return_result
135
138
 
136
139
    def _shorten(self, x):
137
140
        if len(x) > 70:
145
148
        return t
146
149
 
147
150
 
148
 
class LogDecoratorServer(DecoratorServer):
149
 
    """Server for testing."""
150
 
 
151
 
    def get_decorator_class(self):
152
 
        return TransportLogDecorator
153
 
 
154
 
 
155
151
def get_test_permutations():
156
152
    """Return the permutations to be used in testing."""
157
 
    return [(TransportLogDecorator, LogDecoratorServer)]
 
153
    from bzrlib.tests import test_server
 
154
    return [(TransportLogDecorator, test_server.LogDecoratorServer)]