hgext/blackbox.py
author Anton Shestakov <engored@ya.ru>
Mon, 22 Sep 2014 23:46:38 +0900
branchstable
changeset 22506 6e1fbcb18a75
parent 19230 6d6f148cada9
child 23877 7cc77030c557
permissions -rw-r--r--
hgweb: fail if an invalid command was supplied in url path (issue4071) Traditionally, the way to specify a command for hgweb was to use url query arguments (e.g. "?cmd=batch"). If the command is unknown to hgweb, it gives an error (e.g. "400 no such method: badcmd"). But there's also another way to specify a command: as a url path fragment (e.g. "/graph"). Before, hgweb was made forgiving (looks like it was made in 44c5157474e7) and user could put any unknown command in the url. If hgweb couldn't understand it, it would just silently fall back to the default command, which depends on the actual style (e.g. for paper it's shortlog, for monoblue it's summary). This was inconsistent and was breaking some tools that rely on http status codes (as noted in the issue4071). So this patch changes that behavior to the more consistent one, i.e. hgweb will now return "400 no such method: badcmd". So if some tool was relying on having an invalid command return http status code 200 and also have some information, then it will stop working. That is, if somebody typed foobar when they really meant shortlog (and the user was lucky enough to choose a style where the default command is shortlog too), that fact will now be revealed. Code-wise, the changed if block is only relevant when there's no "?cmd" query parameter (i.e. only when command is specified as a url path fragment), and looks like the removed else branch was there only for falling back to default command. With that removed, the rest of the code works as expected: it looks at the command, and if it's not known, raises a proper ErrorResponse exception with an appropriate message. Evidently, there were no tests that required the old behavior. But, frankly, I don't know any way to tell if anyone actually exploited such forgiving behavior in some in-house tool.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
18676
1506eb487ddd blackbox: fix copyright
Bryan O'Sullivan <bryano@fb.com>
parents: 18675
diff changeset
     1
# blackbox.py - log repository events to a file for post-mortem debugging
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
     2
#
18676
1506eb487ddd blackbox: fix copyright
Bryan O'Sullivan <bryano@fb.com>
parents: 18675
diff changeset
     3
# Copyright 2010 Nicolas Dumazet
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
     4
# Copyright 2013 Facebook, Inc.
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
     5
#
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
     6
# This software may be used and distributed according to the terms of the
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
     7
# GNU General Public License version 2 or any later version.
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
     8
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
     9
"""log repository events to a blackbox for debugging
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    10
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    11
Logs event information to .hg/blackbox.log to help debug and diagnose problems.
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    12
The events that get logged can be configured via the blackbox.track config key.
19162
27013ace80eb blackbox: fix literal block syntax
Takumi IINO <trot.thunder@gmail.com>
parents: 19066
diff changeset
    13
Examples::
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    14
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    15
  [blackbox]
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    16
  track = *
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    17
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    18
  [blackbox]
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    19
  track = command, commandfinish, commandexception, exthook, pythonhook
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    20
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    21
  [blackbox]
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    22
  track = incoming
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    23
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    24
  [blackbox]
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    25
  # limit the size of a log file
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    26
  maxsize = 1.5 MB
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    27
  # rotate up to N log files when the current one gets too big
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    28
  maxfiles = 3
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    29
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    30
"""
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    31
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    32
from mercurial import util, cmdutil
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    33
from mercurial.i18n import _
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    34
import errno, os, re
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    35
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    36
cmdtable = {}
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    37
command = cmdutil.command(cmdtable)
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    38
testedwith = 'internal'
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    39
lastblackbox = None
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    40
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    41
def wrapui(ui):
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    42
    class blackboxui(ui.__class__):
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    43
        @util.propertycache
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    44
        def track(self):
19052
63a783d1ac85 blackbox: fix a case of name capture
Bryan O'Sullivan <bryano@fb.com>
parents: 18831
diff changeset
    45
            return self.configlist('blackbox', 'track', ['*'])
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    46
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    47
        def _openlogfile(self):
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    48
            def rotate(oldpath, newpath):
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    49
                try:
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    50
                    os.unlink(newpath)
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    51
                except OSError, err:
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    52
                    if err.errno != errno.ENOENT:
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    53
                        self.debug("warning: cannot remove '%s': %s\n" %
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    54
                                   (newpath, err.strerror))
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    55
                try:
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    56
                    if newpath:
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    57
                        os.rename(oldpath, newpath)
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    58
                except OSError, err:
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    59
                    if err.errno != errno.ENOENT:
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    60
                        self.debug("warning: cannot rename '%s' to '%s': %s\n" %
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    61
                                   (newpath, oldpath, err.strerror))
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    62
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    63
            fp = self._bbopener('blackbox.log', 'a')
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    64
            maxsize = self.configbytes('blackbox', 'maxsize', 1048576)
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    65
            if maxsize > 0:
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    66
                st = os.fstat(fp.fileno())
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    67
                if st.st_size >= maxsize:
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    68
                    path = fp.name
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    69
                    fp.close()
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    70
                    maxfiles = self.configint('blackbox', 'maxfiles', 7)
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    71
                    for i in xrange(maxfiles - 1, 1, -1):
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    72
                        rotate(oldpath='%s.%d' % (path, i - 1),
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    73
                               newpath='%s.%d' % (path, i))
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    74
                    rotate(oldpath=path,
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    75
                           newpath=maxfiles > 0 and path + '.1')
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    76
                    fp = self._bbopener('blackbox.log', 'a')
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    77
            return fp
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    78
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    79
        def log(self, event, *msg, **opts):
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    80
            global lastblackbox
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    81
            super(blackboxui, self).log(event, *msg, **opts)
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    82
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    83
            if not '*' in self.track and not event in self.track:
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    84
                return
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    85
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    86
            if util.safehasattr(self, '_blackbox'):
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    87
                blackbox = self._blackbox
18831
17f6644a2fbc blackbox: defer opening a log file until needed (issue3869)
Bryan O'Sullivan <bryano@fb.com>
parents: 18810
diff changeset
    88
            elif util.safehasattr(self, '_bbopener'):
17f6644a2fbc blackbox: defer opening a log file until needed (issue3869)
Bryan O'Sullivan <bryano@fb.com>
parents: 18810
diff changeset
    89
                try:
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    90
                    self._blackbox = self._openlogfile()
18831
17f6644a2fbc blackbox: defer opening a log file until needed (issue3869)
Bryan O'Sullivan <bryano@fb.com>
parents: 18810
diff changeset
    91
                except (IOError, OSError), err:
17f6644a2fbc blackbox: defer opening a log file until needed (issue3869)
Bryan O'Sullivan <bryano@fb.com>
parents: 18810
diff changeset
    92
                    self.debug('warning: cannot write to blackbox.log: %s\n' %
17f6644a2fbc blackbox: defer opening a log file until needed (issue3869)
Bryan O'Sullivan <bryano@fb.com>
parents: 18810
diff changeset
    93
                               err.strerror)
17f6644a2fbc blackbox: defer opening a log file until needed (issue3869)
Bryan O'Sullivan <bryano@fb.com>
parents: 18810
diff changeset
    94
                    del self._bbopener
17f6644a2fbc blackbox: defer opening a log file until needed (issue3869)
Bryan O'Sullivan <bryano@fb.com>
parents: 18810
diff changeset
    95
                    self._blackbox = None
17f6644a2fbc blackbox: defer opening a log file until needed (issue3869)
Bryan O'Sullivan <bryano@fb.com>
parents: 18810
diff changeset
    96
                blackbox = self._blackbox
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    97
            else:
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    98
                # certain ui instances exist outside the context of
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    99
                # a repo, so just default to the last blackbox that
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   100
                # was seen.
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   101
                blackbox = lastblackbox
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   102
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   103
            if blackbox:
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   104
                date = util.datestr(None, '%Y/%m/%d %H:%M:%S')
18787
f56278a0a0c5 blackbox: use util.getuser for portability
Bryan O'Sullivan <bryano@fb.com>
parents: 18786
diff changeset
   105
                user = util.getuser()
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   106
                formattedmsg = msg[0] % msg[1:]
18786
ed39a8f94e95 blackbox: prevent failed I/O from causing hg to abort
Bryan O'Sullivan <bryano@fb.com>
parents: 18676
diff changeset
   107
                try:
ed39a8f94e95 blackbox: prevent failed I/O from causing hg to abort
Bryan O'Sullivan <bryano@fb.com>
parents: 18676
diff changeset
   108
                    blackbox.write('%s %s> %s' % (date, user, formattedmsg))
ed39a8f94e95 blackbox: prevent failed I/O from causing hg to abort
Bryan O'Sullivan <bryano@fb.com>
parents: 18676
diff changeset
   109
                except IOError, err:
ed39a8f94e95 blackbox: prevent failed I/O from causing hg to abort
Bryan O'Sullivan <bryano@fb.com>
parents: 18676
diff changeset
   110
                    self.debug('warning: cannot write to blackbox.log: %s\n' %
ed39a8f94e95 blackbox: prevent failed I/O from causing hg to abort
Bryan O'Sullivan <bryano@fb.com>
parents: 18676
diff changeset
   111
                               err.strerror)
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   112
                lastblackbox = blackbox
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   113
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   114
        def setrepo(self, repo):
18831
17f6644a2fbc blackbox: defer opening a log file until needed (issue3869)
Bryan O'Sullivan <bryano@fb.com>
parents: 18810
diff changeset
   115
            self._bbopener = repo.opener
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   116
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   117
    ui.__class__ = blackboxui
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   118
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   119
def uisetup(ui):
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   120
    wrapui(ui)
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   121
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   122
def reposetup(ui, repo):
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   123
    # During 'hg pull' a httppeer repo is created to represent the remote repo.
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   124
    # It doesn't have a .hg directory to put a blackbox in, so we don't do
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   125
    # the blackbox setup for it.
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   126
    if not repo.local():
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   127
        return
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   128
19230
6d6f148cada9 blackbox: fix blackbox causing exceptions in tests
Durham Goode <durham@fb.com>
parents: 19162
diff changeset
   129
    if util.safehasattr(ui, 'setrepo'):
6d6f148cada9 blackbox: fix blackbox causing exceptions in tests
Durham Goode <durham@fb.com>
parents: 19162
diff changeset
   130
        ui.setrepo(repo)
18673
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   131
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   132
@command('^blackbox',
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   133
    [('l', 'limit', 10, _('the number of events to show')),
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   134
    ],
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   135
    _('hg blackbox [OPTION]...'))
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   136
def blackbox(ui, repo, *revs, **opts):
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   137
    '''view the recent repository events
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   138
    '''
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   139
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   140
    if not os.path.exists(repo.join('blackbox.log')):
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   141
        return
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   142
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   143
    limit = opts.get('limit')
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   144
    blackbox = repo.opener('blackbox.log', 'r')
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   145
    lines = blackbox.read().split('\n')
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   146
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   147
    count = 0
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   148
    output = []
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   149
    for line in reversed(lines):
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   150
        if count >= limit:
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   151
            break
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   152
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   153
        # count the commands by matching lines like: 2013/01/23 19:13:36 root>
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   154
        if re.match('^\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} .*> .*', line):
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   155
            count += 1
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   156
        output.append(line)
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   157
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   158
    ui.status('\n'.join(reversed(output)))