mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2024-12-23 23:02:25 +00:00
Merge pull request #563 from tahoe-lafs/2987.log_call_deferred
Add Eliot logging helper Fixes: ticket:2987
This commit is contained in:
commit
e4242704b1
0
newsfragments/2987.minor
Normal file
0
newsfragments/2987.minor
Normal file
@ -1764,10 +1764,10 @@ class Downloader(QueueMixin, WriteFileMixin):
|
|||||||
d.addCallback(scan_listing)
|
d.addCallback(scan_listing)
|
||||||
return d.addActionFinish()
|
return d.addActionFinish()
|
||||||
|
|
||||||
|
@eliotutil.log_call_deferred(SCAN_REMOTE_COLLECTIVE.action_type)
|
||||||
def _scan_remote_collective(self, scan_self=False):
|
def _scan_remote_collective(self, scan_self=False):
|
||||||
scan_batch = {} # path -> [(filenode, metadata)]
|
scan_batch = {} # path -> [(filenode, metadata)]
|
||||||
with SCAN_REMOTE_COLLECTIVE().context():
|
d = DeferredContext(self._collective_dirnode.list())
|
||||||
d = DeferredContext(self._collective_dirnode.list())
|
|
||||||
def scan_collective(dirmap):
|
def scan_collective(dirmap):
|
||||||
d2 = DeferredContext(defer.succeed(None))
|
d2 = DeferredContext(defer.succeed(None))
|
||||||
for dir_name in dirmap:
|
for dir_name in dirmap:
|
||||||
@ -1806,26 +1806,26 @@ class Downloader(QueueMixin, WriteFileMixin):
|
|||||||
self._call_hook(None, 'processed', async=True) # await this maybe-Deferred??
|
self._call_hook(None, 'processed', async=True) # await this maybe-Deferred??
|
||||||
|
|
||||||
d.addCallback(_filter_batch_to_deque)
|
d.addCallback(_filter_batch_to_deque)
|
||||||
return d.addActionFinish()
|
return d.result
|
||||||
|
|
||||||
def _scan_delay(self):
|
def _scan_delay(self):
|
||||||
return self._poll_interval
|
return self._poll_interval
|
||||||
|
|
||||||
|
@eliotutil.log_call_deferred(PERFORM_SCAN.action_type)
|
||||||
@eliotutil.inline_callbacks
|
@eliotutil.inline_callbacks
|
||||||
def _perform_scan(self):
|
def _perform_scan(self):
|
||||||
with PERFORM_SCAN():
|
try:
|
||||||
try:
|
yield self._scan_remote_collective()
|
||||||
yield self._scan_remote_collective()
|
self._status_reporter(
|
||||||
self._status_reporter(
|
True, 'Magic folder is working',
|
||||||
True, 'Magic folder is working',
|
'Last scan: %s' % self.nice_current_time(),
|
||||||
'Last scan: %s' % self.nice_current_time(),
|
)
|
||||||
)
|
except Exception as e:
|
||||||
except Exception as e:
|
write_traceback()
|
||||||
write_traceback()
|
self._status_reporter(
|
||||||
self._status_reporter(
|
False, 'Remote scan has failed: %s' % str(e),
|
||||||
False, 'Remote scan has failed: %s' % str(e),
|
'Last attempted at %s' % self.nice_current_time(),
|
||||||
'Last attempted at %s' % self.nice_current_time(),
|
)
|
||||||
)
|
|
||||||
|
|
||||||
def _process(self, item):
|
def _process(self, item):
|
||||||
"""
|
"""
|
||||||
|
@ -21,6 +21,7 @@ from testtools import (
|
|||||||
)
|
)
|
||||||
from testtools.matchers import (
|
from testtools.matchers import (
|
||||||
Is,
|
Is,
|
||||||
|
IsInstance,
|
||||||
MatchesStructure,
|
MatchesStructure,
|
||||||
Equals,
|
Equals,
|
||||||
AfterPreprocessing,
|
AfterPreprocessing,
|
||||||
@ -28,6 +29,7 @@ from testtools.matchers import (
|
|||||||
from testtools.twistedsupport import (
|
from testtools.twistedsupport import (
|
||||||
has_no_result,
|
has_no_result,
|
||||||
succeeded,
|
succeeded,
|
||||||
|
failed,
|
||||||
)
|
)
|
||||||
|
|
||||||
from eliot import (
|
from eliot import (
|
||||||
@ -55,6 +57,7 @@ from .eliotutil import (
|
|||||||
from ..util.eliotutil import (
|
from ..util.eliotutil import (
|
||||||
eliot_friendly_generator_function,
|
eliot_friendly_generator_function,
|
||||||
inline_callbacks,
|
inline_callbacks,
|
||||||
|
log_call_deferred,
|
||||||
_parse_destination_description,
|
_parse_destination_description,
|
||||||
_EliotLogging,
|
_EliotLogging,
|
||||||
)
|
)
|
||||||
@ -527,3 +530,44 @@ class EliotLoggingTests(TestCase):
|
|||||||
len, Equals(1),
|
len, Equals(1),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class LogCallDeferredTests(TestCase):
|
||||||
|
"""
|
||||||
|
Tests for ``log_call_deferred``.
|
||||||
|
"""
|
||||||
|
@capture_logging(
|
||||||
|
lambda self, logger:
|
||||||
|
assertHasAction(self, logger, u"the-action", succeeded=True),
|
||||||
|
)
|
||||||
|
def test_return_value(self, logger):
|
||||||
|
"""
|
||||||
|
The decorated function's return value is passed through.
|
||||||
|
"""
|
||||||
|
result = object()
|
||||||
|
@log_call_deferred(action_type=u"the-action")
|
||||||
|
def f():
|
||||||
|
return result
|
||||||
|
self.assertThat(f(), succeeded(Is(result)))
|
||||||
|
|
||||||
|
@capture_logging(
|
||||||
|
lambda self, logger:
|
||||||
|
assertHasAction(self, logger, u"the-action", succeeded=False),
|
||||||
|
)
|
||||||
|
def test_raise_exception(self, logger):
|
||||||
|
"""
|
||||||
|
An exception raised by the decorated function is passed through.
|
||||||
|
"""
|
||||||
|
class Result(Exception):
|
||||||
|
pass
|
||||||
|
@log_call_deferred(action_type=u"the-action")
|
||||||
|
def f():
|
||||||
|
raise Result()
|
||||||
|
self.assertThat(
|
||||||
|
f(),
|
||||||
|
failed(
|
||||||
|
AfterPreprocessing(
|
||||||
|
lambda f: f.value,
|
||||||
|
IsInstance(Result),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
@ -41,6 +41,7 @@ from .eliotutil import (
|
|||||||
)
|
)
|
||||||
from ..util.eliotutil import (
|
from ..util.eliotutil import (
|
||||||
inline_callbacks,
|
inline_callbacks,
|
||||||
|
log_call_deferred,
|
||||||
)
|
)
|
||||||
|
|
||||||
_debug = False
|
_debug = False
|
||||||
@ -523,6 +524,7 @@ class FileOperationsHelper(object):
|
|||||||
self._inotify = fake_inotify # fixme?
|
self._inotify = fake_inotify # fixme?
|
||||||
self._fake_inotify = inject_events
|
self._fake_inotify = inject_events
|
||||||
|
|
||||||
|
@log_call_deferred(action_type=u"fileops:move")
|
||||||
def move(self, from_path_u, to_path_u):
|
def move(self, from_path_u, to_path_u):
|
||||||
from_fname = from_path_u
|
from_fname = from_path_u
|
||||||
to_fname = to_path_u
|
to_fname = to_path_u
|
||||||
@ -534,6 +536,7 @@ class FileOperationsHelper(object):
|
|||||||
# self._uploader._notifier.event(to_filepath(from_fname), self._inotify.IN_MOVED_FROM)
|
# self._uploader._notifier.event(to_filepath(from_fname), self._inotify.IN_MOVED_FROM)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
@log_call_deferred(action_type=u"fileops:write")
|
||||||
def write(self, path_u, contents):
|
def write(self, path_u, contents):
|
||||||
fname = path_u
|
fname = path_u
|
||||||
if not os.path.exists(fname):
|
if not os.path.exists(fname):
|
||||||
@ -546,6 +549,7 @@ class FileOperationsHelper(object):
|
|||||||
self._maybe_notify(fname, self._inotify.IN_CLOSE_WRITE)
|
self._maybe_notify(fname, self._inotify.IN_CLOSE_WRITE)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
@log_call_deferred(action_type=u"fileops:mkdir")
|
||||||
def mkdir(self, path_u):
|
def mkdir(self, path_u):
|
||||||
fname = path_u
|
fname = path_u
|
||||||
d = self._uploader.set_hook('inotify')
|
d = self._uploader.set_hook('inotify')
|
||||||
@ -553,6 +557,7 @@ class FileOperationsHelper(object):
|
|||||||
self._maybe_notify(fname, self._inotify.IN_CREATE | self._inotify.IN_ISDIR)
|
self._maybe_notify(fname, self._inotify.IN_CREATE | self._inotify.IN_ISDIR)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
@log_call_deferred(action_type=u"fileops:delete")
|
||||||
def delete(self, path_u):
|
def delete(self, path_u):
|
||||||
fname = path_u
|
fname = path_u
|
||||||
d = self._uploader.set_hook('inotify')
|
d = self._uploader.set_hook('inotify')
|
||||||
|
@ -53,17 +53,17 @@ from attr.validators import (
|
|||||||
from eliot import (
|
from eliot import (
|
||||||
ILogger,
|
ILogger,
|
||||||
Message,
|
Message,
|
||||||
|
Field,
|
||||||
FileDestination,
|
FileDestination,
|
||||||
add_destinations,
|
add_destinations,
|
||||||
remove_destination,
|
remove_destination,
|
||||||
write_traceback,
|
write_traceback,
|
||||||
)
|
start_action,
|
||||||
from eliot import (
|
|
||||||
Field,
|
|
||||||
)
|
)
|
||||||
from eliot._validation import (
|
from eliot._validation import (
|
||||||
ValidationError,
|
ValidationError,
|
||||||
)
|
)
|
||||||
|
from eliot.twisted import DeferredContext
|
||||||
|
|
||||||
from twisted.python.usage import (
|
from twisted.python.usage import (
|
||||||
UsageError,
|
UsageError,
|
||||||
@ -81,6 +81,7 @@ from twisted.logger import (
|
|||||||
)
|
)
|
||||||
from twisted.internet.defer import (
|
from twisted.internet.defer import (
|
||||||
inlineCallbacks,
|
inlineCallbacks,
|
||||||
|
maybeDeferred,
|
||||||
)
|
)
|
||||||
from twisted.application.service import Service
|
from twisted.application.service import Service
|
||||||
|
|
||||||
@ -470,3 +471,20 @@ class _DestinationParser(object):
|
|||||||
|
|
||||||
|
|
||||||
_parse_destination_description = _DestinationParser().parse
|
_parse_destination_description = _DestinationParser().parse
|
||||||
|
|
||||||
|
def log_call_deferred(action_type):
|
||||||
|
"""
|
||||||
|
Like ``eliot.log_call`` but for functions which return ``Deferred``.
|
||||||
|
"""
|
||||||
|
def decorate_log_call_deferred(f):
|
||||||
|
@wraps(f)
|
||||||
|
def logged_f(*a, **kw):
|
||||||
|
# Use the action's context method to avoid ending the action when
|
||||||
|
# the `with` block ends.
|
||||||
|
with start_action(action_type=action_type).context():
|
||||||
|
# Use addActionFinish so that the action finishes when the
|
||||||
|
# Deferred fires.
|
||||||
|
d = maybeDeferred(f, *a, **kw)
|
||||||
|
return DeferredContext(d).addActionFinish()
|
||||||
|
return logged_f
|
||||||
|
return decorate_log_call_deferred
|
||||||
|
Loading…
Reference in New Issue
Block a user