69 command = registrar.command(cmdtable) |
69 command = registrar.command(cmdtable) |
70 |
70 |
71 configtable = {} |
71 configtable = {} |
72 configitem = registrar.configitem(configtable) |
72 configitem = registrar.configitem(configtable) |
73 |
73 |
74 configitem('blackbox', 'dirty', |
74 configitem( |
75 default=False, |
75 'blackbox', 'dirty', default=False, |
76 ) |
76 ) |
77 configitem('blackbox', 'maxsize', |
77 configitem( |
78 default='1 MB', |
78 'blackbox', 'maxsize', default='1 MB', |
79 ) |
79 ) |
80 configitem('blackbox', 'logsource', |
80 configitem( |
81 default=False, |
81 'blackbox', 'logsource', default=False, |
82 ) |
82 ) |
83 configitem('blackbox', 'maxfiles', |
83 configitem( |
84 default=7, |
84 'blackbox', 'maxfiles', default=7, |
85 ) |
85 ) |
86 configitem('blackbox', 'track', |
86 configitem( |
87 default=lambda: ['*'], |
87 'blackbox', 'track', default=lambda: ['*'], |
88 ) |
88 ) |
89 configitem('blackbox', 'ignore', |
89 configitem( |
|
90 'blackbox', |
|
91 'ignore', |
90 default=lambda: ['chgserver', 'cmdserver', 'extension'], |
92 default=lambda: ['chgserver', 'cmdserver', 'extension'], |
91 ) |
93 ) |
92 configitem('blackbox', 'date-format', |
94 configitem( |
93 default='%Y/%m/%d %H:%M:%S', |
95 'blackbox', 'date-format', default='%Y/%m/%d %H:%M:%S', |
94 ) |
96 ) |
95 |
97 |
96 _lastlogger = loggingutil.proxylogger() |
98 _lastlogger = loggingutil.proxylogger() |
|
99 |
97 |
100 |
98 class blackboxlogger(object): |
101 class blackboxlogger(object): |
99 def __init__(self, ui, repo): |
102 def __init__(self, ui, repo): |
100 self._repo = repo |
103 self._repo = repo |
101 self._trackedevents = set(ui.configlist('blackbox', 'track')) |
104 self._trackedevents = set(ui.configlist('blackbox', 'track')) |
103 self._maxfiles = ui.configint('blackbox', 'maxfiles') |
106 self._maxfiles = ui.configint('blackbox', 'maxfiles') |
104 self._maxsize = ui.configbytes('blackbox', 'maxsize') |
107 self._maxsize = ui.configbytes('blackbox', 'maxsize') |
105 self._inlog = False |
108 self._inlog = False |
106 |
109 |
107 def tracked(self, event): |
110 def tracked(self, event): |
108 return ((b'*' in self._trackedevents |
111 return ( |
109 and event not in self._ignoredevents) |
112 b'*' in self._trackedevents and event not in self._ignoredevents |
110 or event in self._trackedevents) |
113 ) or event in self._trackedevents |
111 |
114 |
112 def log(self, ui, event, msg, opts): |
115 def log(self, ui, event, msg, opts): |
113 # self._log() -> ctx.dirty() may create new subrepo instance, which |
116 # self._log() -> ctx.dirty() may create new subrepo instance, which |
114 # ui is derived from baseui. So the recursion guard in ui.log() |
117 # ui is derived from baseui. So the recursion guard in ui.log() |
115 # doesn't work as it's local to the ui instance. |
118 # doesn't work as it's local to the ui instance. |
127 user = procutil.getuser() |
130 user = procutil.getuser() |
128 pid = '%d' % procutil.getpid() |
131 pid = '%d' % procutil.getpid() |
129 changed = '' |
132 changed = '' |
130 ctx = self._repo[None] |
133 ctx = self._repo[None] |
131 parents = ctx.parents() |
134 parents = ctx.parents() |
132 rev = ('+'.join([hex(p.node()) for p in parents])) |
135 rev = '+'.join([hex(p.node()) for p in parents]) |
133 if (ui.configbool('blackbox', 'dirty') and |
136 if ui.configbool('blackbox', 'dirty') and ctx.dirty( |
134 ctx.dirty(missing=True, merge=False, branch=False)): |
137 missing=True, merge=False, branch=False |
|
138 ): |
135 changed = '+' |
139 changed = '+' |
136 if ui.configbool('blackbox', 'logsource'): |
140 if ui.configbool('blackbox', 'logsource'): |
137 src = ' [%s]' % event |
141 src = ' [%s]' % event |
138 else: |
142 else: |
139 src = '' |
143 src = '' |
140 try: |
144 try: |
141 fmt = '%s %s @%s%s (%s)%s> %s' |
145 fmt = '%s %s @%s%s (%s)%s> %s' |
142 args = (date, user, rev, changed, pid, src, msg) |
146 args = (date, user, rev, changed, pid, src, msg) |
143 with loggingutil.openlogfile( |
147 with loggingutil.openlogfile( |
144 ui, self._repo.vfs, name='blackbox.log', |
148 ui, |
145 maxfiles=self._maxfiles, maxsize=self._maxsize) as fp: |
149 self._repo.vfs, |
|
150 name='blackbox.log', |
|
151 maxfiles=self._maxfiles, |
|
152 maxsize=self._maxsize, |
|
153 ) as fp: |
146 fp.write(fmt % args) |
154 fp.write(fmt % args) |
147 except (IOError, OSError) as err: |
155 except (IOError, OSError) as err: |
148 # deactivate this to avoid failed logging again |
156 # deactivate this to avoid failed logging again |
149 self._trackedevents.clear() |
157 self._trackedevents.clear() |
150 ui.debug('warning: cannot write to blackbox.log: %s\n' % |
158 ui.debug( |
151 encoding.strtolocal(err.strerror)) |
159 'warning: cannot write to blackbox.log: %s\n' |
|
160 % encoding.strtolocal(err.strerror) |
|
161 ) |
152 return |
162 return |
153 _lastlogger.logger = self |
163 _lastlogger.logger = self |
154 |
164 |
|
165 |
155 def uipopulate(ui): |
166 def uipopulate(ui): |
156 ui.setlogger(b'blackbox', _lastlogger) |
167 ui.setlogger(b'blackbox', _lastlogger) |
|
168 |
157 |
169 |
158 def reposetup(ui, repo): |
170 def reposetup(ui, repo): |
159 # During 'hg pull' a httppeer repo is created to represent the remote repo. |
171 # During 'hg pull' a httppeer repo is created to represent the remote repo. |
160 # It doesn't have a .hg directory to put a blackbox in, so we don't do |
172 # It doesn't have a .hg directory to put a blackbox in, so we don't do |
161 # the blackbox setup for it. |
173 # the blackbox setup for it. |
172 if _lastlogger.logger is None: |
184 if _lastlogger.logger is None: |
173 _lastlogger.logger = logger |
185 _lastlogger.logger = logger |
174 |
186 |
175 repo._wlockfreeprefix.add('blackbox.log') |
187 repo._wlockfreeprefix.add('blackbox.log') |
176 |
188 |
177 @command('blackbox', |
189 |
178 [('l', 'limit', 10, _('the number of events to show')), |
190 @command( |
179 ], |
191 'blackbox', |
|
192 [('l', 'limit', 10, _('the number of events to show')),], |
180 _('hg blackbox [OPTION]...'), |
193 _('hg blackbox [OPTION]...'), |
181 helpcategory=command.CATEGORY_MAINTENANCE, |
194 helpcategory=command.CATEGORY_MAINTENANCE, |
182 helpbasic=True) |
195 helpbasic=True, |
|
196 ) |
183 def blackbox(ui, repo, *revs, **opts): |
197 def blackbox(ui, repo, *revs, **opts): |
184 '''view the recent repository events |
198 '''view the recent repository events |
185 ''' |
199 ''' |
186 |
200 |
187 if not repo.vfs.exists('blackbox.log'): |
201 if not repo.vfs.exists('blackbox.log'): |