hgext/blackbox.py
author Gregory Szorc <gregory.szorc@gmail.com>
Wed, 19 Sep 2018 11:17:28 -0700
changeset 39842 97986c9c69d3
parent 38783 e7aa113b14f7
child 40293 c303d65d2e34
permissions -rw-r--r--
verify: start to abstract file verification Currently, the file storage interface has a handful of attributes that are exclusively or near-exclusively used by repo verification code. In order to support verification on non-revlog/alternate storage backends, we'll need to abstract verification so it can be performed in a storage-agnostic way. This commit starts that process. We establish a new verifyintegrity() method on revlogs and expose it to the file storage interface. Most of verify.verifier.checklog() has been ported to this new method. We need a way to represent verification problems. So we invent an interface to represent a verification problem, invent a revlog type to implement that interface, and use it. The arguments to verifyintegrity() will almost certainly change in the future, once more functionality is ported from the verify code. And the "revlogv1" version check is very hacky. (The code in verify is actually buggy because it is comparing the full 32-bit header integer instead of just the revlog version short. I'll likely fix this in a subsequent commit.) Differential Revision: https://phab.mercurial-scm.org/D4701
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.
28246
b862e793ec10 blackbox: log dirty state
timeless <timeless@mozdev.org>
parents: 28245
diff changeset
    13
19162
27013ace80eb blackbox: fix literal block syntax
Takumi IINO <trot.thunder@gmail.com>
parents: 19066
diff changeset
    14
Examples::
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    15
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    16
  [blackbox]
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    17
  track = *
28303
ce24de063aa5 blackbox: rewrite dirty documentation noting it is expensive
timeless <timeless@mozdev.org>
parents: 28248
diff changeset
    18
  # dirty is *EXPENSIVE* (slow);
ce24de063aa5 blackbox: rewrite dirty documentation noting it is expensive
timeless <timeless@mozdev.org>
parents: 28248
diff changeset
    19
  # each log entry indicates `+` if the repository is dirty, like :hg:`id`.
28246
b862e793ec10 blackbox: log dirty state
timeless <timeless@mozdev.org>
parents: 28245
diff changeset
    20
  dirty = True
28305
f5ae291dfedf blackbox: optionally log event source
timeless <timeless@mozdev.org>
parents: 28304
diff changeset
    21
  # record the source of log messages
f5ae291dfedf blackbox: optionally log event source
timeless <timeless@mozdev.org>
parents: 28304
diff changeset
    22
  logsource = True
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    23
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    24
  [blackbox]
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    25
  track = command, commandfinish, commandexception, exthook, pythonhook
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    26
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    27
  [blackbox]
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    28
  track = incoming
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    29
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    30
  [blackbox]
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    31
  # limit the size of a log file
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    32
  maxsize = 1.5 MB
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    33
  # 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
    34
  maxfiles = 3
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
    35
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    36
"""
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    37
28090
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
    38
from __future__ import absolute_import
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
    39
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
    40
import errno
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
    41
import re
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
    42
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    43
from mercurial.i18n import _
28245
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
    44
from mercurial.node import hex
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
    45
28090
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
    46
from mercurial import (
35667
de598e84c244 py3: cast error message to localstr in blackbox.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34972
diff changeset
    47
    encoding,
38783
e7aa113b14f7 global: use pycompat.xrange()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37120
diff changeset
    48
    pycompat,
32337
46ba2cdda476 registrar: move cmdutil.command to registrar module (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32155
diff changeset
    49
    registrar,
28248
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
    50
    ui as uimod,
28090
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
    51
    util,
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
    52
)
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36607
diff changeset
    53
from mercurial.utils import (
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36607
diff changeset
    54
    dateutil,
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36607
diff changeset
    55
    procutil,
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36607
diff changeset
    56
)
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    57
29841
d5883fd055c6 extensions: change magic "shipped with hg" string
Augie Fackler <augie@google.com>
parents: 28552
diff changeset
    58
# Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
25186
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 23877
diff changeset
    59
# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 23877
diff changeset
    60
# be specifying the version(s) of Mercurial they are tested with, or
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 23877
diff changeset
    61
# leave the attribute unspecified.
29841
d5883fd055c6 extensions: change magic "shipped with hg" string
Augie Fackler <augie@google.com>
parents: 28552
diff changeset
    62
testedwith = 'ships-with-hg-core'
33134
7dc090faa8a4 blackbox: minor code reordering
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32412
diff changeset
    63
7dc090faa8a4 blackbox: minor code reordering
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32412
diff changeset
    64
cmdtable = {}
7dc090faa8a4 blackbox: minor code reordering
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32412
diff changeset
    65
command = registrar.command(cmdtable)
7dc090faa8a4 blackbox: minor code reordering
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32412
diff changeset
    66
33135
0a638f37f2d2 configitems: register 'blackbox.maxsize' as an example of 'configbytes'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33134
diff changeset
    67
configtable = {}
0a638f37f2d2 configitems: register 'blackbox.maxsize' as an example of 'configbytes'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33134
diff changeset
    68
configitem = registrar.configitem(configtable)
0a638f37f2d2 configitems: register 'blackbox.maxsize' as an example of 'configbytes'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33134
diff changeset
    69
33189
1df74b71396d configitems: register the 'blackbox.dirty' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33136
diff changeset
    70
configitem('blackbox', 'dirty',
1df74b71396d configitems: register the 'blackbox.dirty' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33136
diff changeset
    71
    default=False,
1df74b71396d configitems: register the 'blackbox.dirty' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33136
diff changeset
    72
)
33135
0a638f37f2d2 configitems: register 'blackbox.maxsize' as an example of 'configbytes'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33134
diff changeset
    73
configitem('blackbox', 'maxsize',
33136
59c135bb31bc blackbox: use a human readable version of the default
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33135
diff changeset
    74
    default='1 MB',
33135
0a638f37f2d2 configitems: register 'blackbox.maxsize' as an example of 'configbytes'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33134
diff changeset
    75
)
33190
0ef40bb20264 configitems: register the 'blackbox.logsource' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33189
diff changeset
    76
configitem('blackbox', 'logsource',
0ef40bb20264 configitems: register the 'blackbox.logsource' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33189
diff changeset
    77
    default=False,
0ef40bb20264 configitems: register the 'blackbox.logsource' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33189
diff changeset
    78
)
34745
0b46440b1b45 configitems: register the 'blackbox.maxfiles' config
Boris Feld <boris.feld@octobus.net>
parents: 34583
diff changeset
    79
configitem('blackbox', 'maxfiles',
0b46440b1b45 configitems: register the 'blackbox.maxfiles' config
Boris Feld <boris.feld@octobus.net>
parents: 34583
diff changeset
    80
    default=7,
0b46440b1b45 configitems: register the 'blackbox.maxfiles' config
Boris Feld <boris.feld@octobus.net>
parents: 34583
diff changeset
    81
)
34517
49b72b6f6d66 configitems: register the 'blackbox.track' config
Boris Feld <boris.feld@octobus.net>
parents: 34300
diff changeset
    82
configitem('blackbox', 'track',
34583
19b2c062654c configitems: fix registration for 'blackbox.track' config
Boris Feld <boris.feld@octobus.net>
parents: 34517
diff changeset
    83
    default=lambda: ['*'],
34517
49b72b6f6d66 configitems: register the 'blackbox.track' config
Boris Feld <boris.feld@octobus.net>
parents: 34300
diff changeset
    84
)
33135
0a638f37f2d2 configitems: register 'blackbox.maxsize' as an example of 'configbytes'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33134
diff changeset
    85
28247
d2c0527af364 blackbox: store the blackbox ui object instead of the log file
timeless <timeless@mozdev.org>
parents: 28246
diff changeset
    86
lastui = None
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
    87
34300
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
    88
def _openlogfile(ui, vfs):
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
    89
    def rotate(oldpath, newpath):
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
    90
        try:
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
    91
            vfs.unlink(newpath)
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
    92
        except OSError as err:
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
    93
            if err.errno != errno.ENOENT:
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
    94
                ui.debug("warning: cannot remove '%s': %s\n" %
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
    95
                         (newpath, err.strerror))
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
    96
        try:
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
    97
            if newpath:
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
    98
                vfs.rename(oldpath, newpath)
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
    99
        except OSError as err:
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
   100
            if err.errno != errno.ENOENT:
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
   101
                ui.debug("warning: cannot rename '%s' to '%s': %s\n" %
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
   102
                         (newpath, oldpath, err.strerror))
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
   103
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
   104
    maxsize = ui.configbytes('blackbox', 'maxsize')
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
   105
    name = 'blackbox.log'
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
   106
    if maxsize > 0:
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
   107
        try:
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
   108
            st = vfs.stat(name)
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
   109
        except OSError:
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
   110
            pass
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
   111
        else:
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
   112
            if st.st_size >= maxsize:
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
   113
                path = vfs.join(name)
34745
0b46440b1b45 configitems: register the 'blackbox.maxfiles' config
Boris Feld <boris.feld@octobus.net>
parents: 34583
diff changeset
   114
                maxfiles = ui.configint('blackbox', 'maxfiles')
38783
e7aa113b14f7 global: use pycompat.xrange()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37120
diff changeset
   115
                for i in pycompat.xrange(maxfiles - 1, 1, -1):
34300
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
   116
                    rotate(oldpath='%s.%d' % (path, i - 1),
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
   117
                           newpath='%s.%d' % (path, i))
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
   118
                rotate(oldpath=path,
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
   119
                       newpath=maxfiles > 0 and path + '.1')
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
   120
    return vfs(name, 'a')
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
   121
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   122
def wrapui(ui):
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   123
    class blackboxui(ui.__class__):
34110
029b33adbd17 blackbox: remove _bbvfs state
Jun Wu <quark@fb.com>
parents: 34109
diff changeset
   124
        @property
029b33adbd17 blackbox: remove _bbvfs state
Jun Wu <quark@fb.com>
parents: 34109
diff changeset
   125
        def _bbvfs(self):
34299
b1d4ac068961 blackbox: do not prevent 'chg init' from working
Jun Wu <quark@fb.com>
parents: 34276
diff changeset
   126
            vfs = None
34110
029b33adbd17 blackbox: remove _bbvfs state
Jun Wu <quark@fb.com>
parents: 34109
diff changeset
   127
            repo = getattr(self, '_bbrepo', None)
029b33adbd17 blackbox: remove _bbvfs state
Jun Wu <quark@fb.com>
parents: 34109
diff changeset
   128
            if repo:
34299
b1d4ac068961 blackbox: do not prevent 'chg init' from working
Jun Wu <quark@fb.com>
parents: 34276
diff changeset
   129
                vfs = repo.vfs
b1d4ac068961 blackbox: do not prevent 'chg init' from working
Jun Wu <quark@fb.com>
parents: 34276
diff changeset
   130
                if not vfs.isdir('.'):
b1d4ac068961 blackbox: do not prevent 'chg init' from working
Jun Wu <quark@fb.com>
parents: 34276
diff changeset
   131
                    vfs = None
b1d4ac068961 blackbox: do not prevent 'chg init' from working
Jun Wu <quark@fb.com>
parents: 34276
diff changeset
   132
            return vfs
34110
029b33adbd17 blackbox: remove _bbvfs state
Jun Wu <quark@fb.com>
parents: 34109
diff changeset
   133
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   134
        @util.propertycache
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   135
        def track(self):
34517
49b72b6f6d66 configitems: register the 'blackbox.track' config
Boris Feld <boris.feld@octobus.net>
parents: 34300
diff changeset
   136
            return self.configlist('blackbox', 'track')
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   137
35724
853bf7d90804 blackbox: if --debug is used, also trace ui.debug() calls
Joerg Sonnenberger <joerg@bec.de>
parents: 35667
diff changeset
   138
        def debug(self, *msg, **opts):
853bf7d90804 blackbox: if --debug is used, also trace ui.debug() calls
Joerg Sonnenberger <joerg@bec.de>
parents: 35667
diff changeset
   139
            super(blackboxui, self).debug(*msg, **opts)
853bf7d90804 blackbox: if --debug is used, also trace ui.debug() calls
Joerg Sonnenberger <joerg@bec.de>
parents: 35667
diff changeset
   140
            if self.debugflag:
35727
05c70675e5b9 blackbox: don't unpack the list while passing into str.join()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35724
diff changeset
   141
                self.log('debug', '%s', ''.join(msg))
35724
853bf7d90804 blackbox: if --debug is used, also trace ui.debug() calls
Joerg Sonnenberger <joerg@bec.de>
parents: 35667
diff changeset
   142
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   143
        def log(self, event, *msg, **opts):
28247
d2c0527af364 blackbox: store the blackbox ui object instead of the log file
timeless <timeless@mozdev.org>
parents: 28246
diff changeset
   144
            global lastui
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   145
            super(blackboxui, self).log(event, *msg, **opts)
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   146
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   147
            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
   148
                return
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   149
34109
cf04db16f583 blackbox: do not cache file objects
Jun Wu <quark@fb.com>
parents: 34108
diff changeset
   150
            if self._bbvfs:
28247
d2c0527af364 blackbox: store the blackbox ui object instead of the log file
timeless <timeless@mozdev.org>
parents: 28246
diff changeset
   151
                ui = self
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   152
            else:
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   153
                # certain ui instances exist outside the context of
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   154
                # a repo, so just default to the last blackbox that
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   155
                # was seen.
28247
d2c0527af364 blackbox: store the blackbox ui object instead of the log file
timeless <timeless@mozdev.org>
parents: 28246
diff changeset
   156
                ui = lastui
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   157
34109
cf04db16f583 blackbox: do not cache file objects
Jun Wu <quark@fb.com>
parents: 34108
diff changeset
   158
            if not ui:
28407
63da8bd0c65e blackbox: guard against recursion from dirty check
timeless <timeless@mozdev.org>
parents: 28305
diff changeset
   159
                return
34299
b1d4ac068961 blackbox: do not prevent 'chg init' from working
Jun Wu <quark@fb.com>
parents: 34276
diff changeset
   160
            vfs = ui._bbvfs
b1d4ac068961 blackbox: do not prevent 'chg init' from working
Jun Wu <quark@fb.com>
parents: 34276
diff changeset
   161
            if not vfs:
b1d4ac068961 blackbox: do not prevent 'chg init' from working
Jun Wu <quark@fb.com>
parents: 34276
diff changeset
   162
                return
b1d4ac068961 blackbox: do not prevent 'chg init' from working
Jun Wu <quark@fb.com>
parents: 34276
diff changeset
   163
34274
a37e18b5f055 blackbox: simplify ui states
Jun Wu <quark@fb.com>
parents: 34110
diff changeset
   164
            repo = getattr(ui, '_bbrepo', None)
a37e18b5f055 blackbox: simplify ui states
Jun Wu <quark@fb.com>
parents: 34110
diff changeset
   165
            if not lastui or repo:
28407
63da8bd0c65e blackbox: guard against recursion from dirty check
timeless <timeless@mozdev.org>
parents: 28305
diff changeset
   166
                lastui = ui
34274
a37e18b5f055 blackbox: simplify ui states
Jun Wu <quark@fb.com>
parents: 34110
diff changeset
   167
            if getattr(ui, '_bbinlog', False):
34109
cf04db16f583 blackbox: do not cache file objects
Jun Wu <quark@fb.com>
parents: 34108
diff changeset
   168
                # recursion and failure guard
28407
63da8bd0c65e blackbox: guard against recursion from dirty check
timeless <timeless@mozdev.org>
parents: 28305
diff changeset
   169
                return
34275
86a5df995880 blackbox: unindent a try block
Jun Wu <quark@fb.com>
parents: 34274
diff changeset
   170
            ui._bbinlog = True
86a5df995880 blackbox: unindent a try block
Jun Wu <quark@fb.com>
parents: 34274
diff changeset
   171
            default = self.configdate('devel', 'default-date')
36607
c6061cadb400 util: extract all date-related utils in utils/dateutil module
Boris Feld <boris.feld@octobus.net>
parents: 35727
diff changeset
   172
            date = dateutil.datestr(default, '%Y/%m/%d %H:%M:%S')
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36607
diff changeset
   173
            user = procutil.getuser()
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36607
diff changeset
   174
            pid = '%d' % procutil.getpid()
34275
86a5df995880 blackbox: unindent a try block
Jun Wu <quark@fb.com>
parents: 34274
diff changeset
   175
            formattedmsg = msg[0] % msg[1:]
86a5df995880 blackbox: unindent a try block
Jun Wu <quark@fb.com>
parents: 34274
diff changeset
   176
            rev = '(unknown)'
86a5df995880 blackbox: unindent a try block
Jun Wu <quark@fb.com>
parents: 34274
diff changeset
   177
            changed = ''
86a5df995880 blackbox: unindent a try block
Jun Wu <quark@fb.com>
parents: 34274
diff changeset
   178
            if repo:
86a5df995880 blackbox: unindent a try block
Jun Wu <quark@fb.com>
parents: 34274
diff changeset
   179
                ctx = repo[None]
86a5df995880 blackbox: unindent a try block
Jun Wu <quark@fb.com>
parents: 34274
diff changeset
   180
                parents = ctx.parents()
86a5df995880 blackbox: unindent a try block
Jun Wu <quark@fb.com>
parents: 34274
diff changeset
   181
                rev = ('+'.join([hex(p.node()) for p in parents]))
86a5df995880 blackbox: unindent a try block
Jun Wu <quark@fb.com>
parents: 34274
diff changeset
   182
                if (ui.configbool('blackbox', 'dirty') and
86a5df995880 blackbox: unindent a try block
Jun Wu <quark@fb.com>
parents: 34274
diff changeset
   183
                    ctx.dirty(missing=True, merge=False, branch=False)):
86a5df995880 blackbox: unindent a try block
Jun Wu <quark@fb.com>
parents: 34274
diff changeset
   184
                    changed = '+'
86a5df995880 blackbox: unindent a try block
Jun Wu <quark@fb.com>
parents: 34274
diff changeset
   185
            if ui.configbool('blackbox', 'logsource'):
86a5df995880 blackbox: unindent a try block
Jun Wu <quark@fb.com>
parents: 34274
diff changeset
   186
                src = ' [%s]' % event
86a5df995880 blackbox: unindent a try block
Jun Wu <quark@fb.com>
parents: 34274
diff changeset
   187
            else:
86a5df995880 blackbox: unindent a try block
Jun Wu <quark@fb.com>
parents: 34274
diff changeset
   188
                src = ''
28407
63da8bd0c65e blackbox: guard against recursion from dirty check
timeless <timeless@mozdev.org>
parents: 28305
diff changeset
   189
            try:
34275
86a5df995880 blackbox: unindent a try block
Jun Wu <quark@fb.com>
parents: 34274
diff changeset
   190
                fmt = '%s %s @%s%s (%s)%s> %s'
86a5df995880 blackbox: unindent a try block
Jun Wu <quark@fb.com>
parents: 34274
diff changeset
   191
                args = (date, user, rev, changed, pid, src, formattedmsg)
34300
e6723c939344 blackbox: move _openlogfile to a separate method
Jun Wu <quark@fb.com>
parents: 34299
diff changeset
   192
                with _openlogfile(ui, vfs) as fp:
34275
86a5df995880 blackbox: unindent a try block
Jun Wu <quark@fb.com>
parents: 34274
diff changeset
   193
                    fp.write(fmt % args)
86a5df995880 blackbox: unindent a try block
Jun Wu <quark@fb.com>
parents: 34274
diff changeset
   194
            except (IOError, OSError) as err:
86a5df995880 blackbox: unindent a try block
Jun Wu <quark@fb.com>
parents: 34274
diff changeset
   195
                self.debug('warning: cannot write to blackbox.log: %s\n' %
35667
de598e84c244 py3: cast error message to localstr in blackbox.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34972
diff changeset
   196
                           encoding.strtolocal(err.strerror))
34275
86a5df995880 blackbox: unindent a try block
Jun Wu <quark@fb.com>
parents: 34274
diff changeset
   197
                # do not restore _bbinlog intentionally to avoid failed
86a5df995880 blackbox: unindent a try block
Jun Wu <quark@fb.com>
parents: 34274
diff changeset
   198
                # logging again
86a5df995880 blackbox: unindent a try block
Jun Wu <quark@fb.com>
parents: 34274
diff changeset
   199
            else:
86a5df995880 blackbox: unindent a try block
Jun Wu <quark@fb.com>
parents: 34274
diff changeset
   200
                ui._bbinlog = False
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   201
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   202
        def setrepo(self, repo):
28248
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
   203
            self._bbrepo = repo
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   204
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   205
    ui.__class__ = blackboxui
28248
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
   206
    uimod.ui = blackboxui
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   207
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   208
def uisetup(ui):
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   209
    wrapui(ui)
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   210
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   211
def reposetup(ui, repo):
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   212
    # 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
   213
    # 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
   214
    # the blackbox setup for it.
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   215
    if not repo.local():
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   216
        return
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
   217
19230
6d6f148cada9 blackbox: fix blackbox causing exceptions in tests
Durham Goode <durham@fb.com>
parents: 19162
diff changeset
   218
    if util.safehasattr(ui, 'setrepo'):
6d6f148cada9 blackbox: fix blackbox causing exceptions in tests
Durham Goode <durham@fb.com>
parents: 19162
diff changeset
   219
        ui.setrepo(repo)
34276
b90bd9a98c8b blackbox: set lastui even if ui.log is not called (issue5518)
Jun Wu <quark@fb.com>
parents: 34275
diff changeset
   220
b90bd9a98c8b blackbox: set lastui even if ui.log is not called (issue5518)
Jun Wu <quark@fb.com>
parents: 34275
diff changeset
   221
        # Set lastui even if ui.log is not called. This gives blackbox a
b90bd9a98c8b blackbox: set lastui even if ui.log is not called (issue5518)
Jun Wu <quark@fb.com>
parents: 34275
diff changeset
   222
        # fallback place to log.
b90bd9a98c8b blackbox: set lastui even if ui.log is not called (issue5518)
Jun Wu <quark@fb.com>
parents: 34275
diff changeset
   223
        global lastui
b90bd9a98c8b blackbox: set lastui even if ui.log is not called (issue5518)
Jun Wu <quark@fb.com>
parents: 34275
diff changeset
   224
        if lastui is None:
b90bd9a98c8b blackbox: set lastui even if ui.log is not called (issue5518)
Jun Wu <quark@fb.com>
parents: 34275
diff changeset
   225
            lastui = ui
b90bd9a98c8b blackbox: set lastui even if ui.log is not called (issue5518)
Jun Wu <quark@fb.com>
parents: 34275
diff changeset
   226
33436
9bb4decd43b0 repovfs: add a ward to check if locks are properly taken
Boris Feld <boris.feld@octobus.net>
parents: 33361
diff changeset
   227
    repo._wlockfreeprefix.add('blackbox.log')
18673
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   228
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   229
@command('^blackbox',
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   230
    [('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
   231
    ],
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   232
    _('hg blackbox [OPTION]...'))
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   233
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
   234
    '''view the recent repository events
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   235
    '''
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   236
28026
a6db1163befa blackbox: refactor use of vfs as _bbvfs
timeless <timeless@mozdev.org>
parents: 28025
diff changeset
   237
    if not repo.vfs.exists('blackbox.log'):
18673
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   238
        return
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   239
34972
375577785f49 py3: handle keyword arguments in hgext/blackbox.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34745
diff changeset
   240
    limit = opts.get(r'limit')
28244
c17d7b1c40be blackbox: rename fp variable
timeless <timeless@mozdev.org>
parents: 28243
diff changeset
   241
    fp = repo.vfs('blackbox.log', 'r')
c17d7b1c40be blackbox: rename fp variable
timeless <timeless@mozdev.org>
parents: 28243
diff changeset
   242
    lines = fp.read().split('\n')
18673
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   243
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   244
    count = 0
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   245
    output = []
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   246
    for line in reversed(lines):
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   247
        if count >= limit:
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   248
            break
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   249
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   250
        # 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
   251
        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
   252
            count += 1
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   253
        output.append(line)
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   254
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
   255
    ui.status('\n'.join(reversed(output)))