Skip to content

Commit

Permalink
Merge pull request #151 from ClusterHQ/optional-logger-112
Browse files Browse the repository at this point in the history
Make Logger optional.

Fixes #112.
  • Loading branch information
itamarst committed Apr 27, 2015
2 parents acc20b6 + 4df1c99 commit 6646d6a
Show file tree
Hide file tree
Showing 24 changed files with 410 additions and 177 deletions.
28 changes: 10 additions & 18 deletions docs/source/actions.rst
Expand Up @@ -37,13 +37,11 @@ Here's a basic example of logging an action:

.. code-block:: python
from eliot import start_action, Logger
from eliot import start_action
logger = Logger()
with start_action(logger, u"yourapp:subsystem:frob"):
x = _beep()
frobinate(x)
with start_action(action_type=u"store_data"):
x = get_data()
store_data(x)
This will log an action start message and if the block finishes successfully an action success message.
If an exception is thrown by the block then an action failure message will be logged along with the exception type and reason as additional fields.
Expand All @@ -70,11 +68,9 @@ Keep in mind that code within the context block that is run after the action is

.. code-block:: python
from eliot import start_action, Logger
logger = Logger()
from eliot import start_action
action = start_action(logger, u"yourapp:subsystem:frob"):
action = start_action(action_type=u"yourapp:subsystem:frob")
try:
with action.context():
x = _beep()
Expand All @@ -90,11 +86,9 @@ You can also explicitly run a function within the action context:

.. code-block:: python
from eliot import start_action, Logger
from eliot import start_action
logger = Logger()
action = start_action(logger, u"yourapp:subsystem:frob")
action = start_action(action_type=u"yourapp:subsystem:frob")
# Call do_something(x=1) in context of action, return its result:
result = action.run(do_something, x=1)
Expand All @@ -106,11 +100,9 @@ You can add fields to both the start message and the success message of an actio

.. code-block:: python
from eliot import start_action, Logger
logger = Logger()
from eliot import start_action
with start_action(logger, u"yourapp:subsystem:frob",
with start_action(action_type=u"yourapp:subsystem:frob",
# Fields added to start message only:
key=123, foo=u"bar") as action:
x = _beep(123)
Expand Down
12 changes: 5 additions & 7 deletions docs/source/fields.rst
Expand Up @@ -22,14 +22,12 @@ Consider the following code sample:

.. code-block:: python
from eliot import start_action, Logger, Message
from eliot import start_action, Message
logger = Logger()
with start_action(logger, u"parent"):
Message.new(x="1").write(logger)
with start_action(logger, u"child"):
Message.new(x="2").write(logger)
with start_action(action_type=u"parent"):
Message.new(x="1").write()
with start_action(action_type=u"child"):
Message.new(x="2").write()
If you sort the resulting messages by their ``task_level`` you will get the tree of messages:

Expand Down
38 changes: 15 additions & 23 deletions docs/source/introduction.rst
Expand Up @@ -67,19 +67,16 @@ For simplicity's sake this example focuses on problems 1 and 3; problem 2 is cov
.. code-block:: python
from __future__ import unicode_literals
from eliot import Logger, Message
logger = Logger()
from eliot import Message
class Person(object):
def __init__(self):
self.seen = set()
def look(self, thing):
msg = Message.new(type="person:look",
person=unicode(self),
at=unicode(thing))
msg.write(logger)
Message.new(message_type="person:look",
person=unicode(self),
at=unicode(thing)).write()
self.seen.add(thing)
Expand All @@ -89,10 +86,9 @@ For simplicity's sake this example focuses on problems 1 and 3; problem 2 is cov
self.contained = []
def travel(self, person):
msg = Message.new(type="place:travel",
person=unicode(person),
place=self.name)
msg.write(logger)
Message.new(message_type="place:travel",
person=unicode(person),
place=self.name).write()
for thing in self.contained:
if isinstance(thing, Place):
thing.travel(person)
Expand All @@ -105,9 +101,8 @@ For simplicity's sake this example focuses on problems 1 and 3; problem 2 is cov
def honeymoon(family):
msg = Message.new(type="honeymoon",
family=[unicode(person) for person in family])
msg.write(logger)
Message.new(message_type="honeymoon",
family=[unicode(person) for person in family]).write()
rome = Place.load("Rome, Italy")
for person in family:
rome.travel(person)
Expand Down Expand Up @@ -139,27 +134,24 @@ In our example we have one task (the honeymoon), an action (travel). We will lea
.. code-block:: python
from __future__ import unicode_literals
from eliot import Logger, Message, start_action, start_task
logger = Logger()
from eliot import Message, start_action, start_task
class Person(object):
def __init__(self):
self.seen = set()
def look(self, thing):
msg = Message.new(message_type="person:look",
person=unicode(self),
at=unicode(thing))
msg.write(logger)
Message.new(message_type="person:look",
person=unicode(self),
at=unicode(thing)).write()
self.seen.add(thing)
class Place(object):
# __init__ and load unchanged from above.
def travel(self, person):
with start_action(logger, "place:travel",
with start_action("place:travel",
person=unicode(person),
place=self.name):
for thing in self.contained:
Expand All @@ -170,7 +162,7 @@ In our example we have one task (the honeymoon), an action (travel). We will lea
def honeymoon(family):
with start_task(logger, "honeymoon",
with start_task("honeymoon",
family=[unicode(person) for person in family]):
rome = Place.load("Rome, Italy")
for person in family:
Expand Down
18 changes: 9 additions & 9 deletions docs/source/messages.rst
Expand Up @@ -10,21 +10,22 @@ Fields therefore can have Unicode names, so either ``unicode`` or ``bytes`` cont
Message values must be supported by JSON: ``int``, ``float``, ``None``, ``unicode``, UTF-8 encoded Unicode as ``bytes``, ``dict`` or ``list``.
The latter two can only be composed of other supported types.

A ``Message`` is written to a ``Logger``, whose purpose is to create scope for unit tests to validate only specific messages.
Typically you will create a ``Logger`` per top-level class you are testing.
You can log a message like this:

.. code-block:: python
from eliot import Message, Logger
from eliot import Message
class YourClass(object):
logger = Logger()
def run(self):
# Create a message with two fields, "key" and "value":
msg = Message.new(key=123, value=u"hello")
# Write the message:
msg.write(self.logger)
msg.write()
Message binding
---------------

You can also create a new ``Message`` from an existing one by binding new values.
New values will override ones on the base ``Message``, but ``bind()`` does not mutate the original ``Message``.
Expand All @@ -44,13 +45,12 @@ You can also log tracebacks when your code hits an unexpected exception:

.. code-block:: python
from eliot import Logger, write_traceback
from eliot import write_traceback
class YourClass(object):
logger = Logger()
def run(self):
try:
dosomething()
except:
write_traceback(self.logger)
write_traceback()
2 changes: 2 additions & 0 deletions docs/source/news.rst
Expand Up @@ -4,6 +4,8 @@ What's New
0.7.0
^^^^^

* Creating your own ``Logger`` instances is no longer necessary; all relevant APIs now default to using a global one.
A new testing decorator (``eliot.testing.capture_logging``) was added to capture global logging.
* Support positional ``Field``-instance arguments to ``fields()`` to make combining existing field types and simple fields more convenient.
Contributed by Jonathan Jacobs.
* ``write_traceback`` and ``writeFailure`` no longer require a ``system`` argument, as the combination of traceback and action context should suffice to discover the origin of the problem.
Expand Down
2 changes: 1 addition & 1 deletion docs/source/output.rst
@@ -1,7 +1,7 @@
Configuring Logging Output
==========================

Destinations are how messages get written out by the ``Logger`` class.
You can register "destinations" to handle logging output.
A destination is a callable that takes a message dictionary.
For example, if we want each message to be encoded in JSON and written on a new line on stdout:

Expand Down
18 changes: 6 additions & 12 deletions docs/source/twisted.rst
Expand Up @@ -37,14 +37,13 @@ Logging Failures

.. code-block:: python
from eliot import Logger, writeFailure
from eliot import writeFailure
class YourClass(object):
logger = Logger()
def run(self):
d = dosomething()
d.addErrback(writeFailure, self.logger)
d.addErrback(writeFailure)
Actions and Deferreds
Expand All @@ -55,13 +54,10 @@ To understand why, consider the following example:

.. code-block:: python
from eliot import startAction, Logger
logger = Logger()
from eliot import startAction
def go():
action = startAction(logger, u"yourapp:subsystem:frob")
action = startAction(action_type=u"yourapp:subsystem:frob")
with action:
d = Deferred()
d.addCallback(gotResult, x=1)
Expand All @@ -81,14 +77,12 @@ Finally, you can unwrap the ``DeferredContext`` and access the wrapped ``Deferre

.. code-block:: python
from eliot import startAction, Logger
from eliot import startAction
from eliot.twisted import DeferredContext
logger = Logger()
def go():
action = startAction(logger, u"yourapp:subsystem:frob")
action = startAction(action_type=u"yourapp:subsystem:frob")
with action.context():
d = DeferredContext(Deferred())
# gotResult(result, x=1) will be called in the context of the action:
Expand Down

0 comments on commit 6646d6a

Please sign in to comment.