Outlets ======= We can configure where ``jotting`` sends logs by choosing new "outlets". Outlets can be any callable object, but we can also use builtin outlets from ``jotting.to`` in order to save logs to a file: .. code-block:: python import requests from jotting import book, to book.distribute(to.File(path="~/Desktop/logbox.txt")) # we can format the title with # the inputs of the function @book.mark("getting {url}") def get_url(url): r = requests.get(url) r.raise_for_status() return r response = get_url("https://google.com") Now we will find a ``logbox.txt`` file on our desktop with the following contents: .. code-block:: text {"metadata": {"title": "getting https://google.com", "timestamps": [1519973286.701371], "tag": "d6154a2a16db4561b151fc43b3781f75", "parent": null, "status": "started"}, "content": {"url": "https://google.com"}} {"metadata": {"title": "getting https://google.com", "timestamps": [1519973286.701371, 1519973286.991931], "tag": "d6154a2a16db4561b151fc43b3781f75", "parent": null, "status": "success", "stop": 1519973286.991928}, "content": {"returned": ""}} In all the examples we've seen so far, ``jotting`` has produced clean nested tree of log statements. However, these saved logs show us that under the hood ``jotting`` isn't magic - each log is a dictionary that contains the information required to reconstruct a history of actions. Your Own Outlets ---------------- You can make your own outlets with the :func:`jotting.to.outlet` decorator. The decorator takes in functions and returns a new :class:`jotting.to.Outlet` class. It expects functions of the form ``(log, *args, **kwargs)`` where ``log`` is a formatted log string generated by a user, and ``*args, **kwargs`` were the parameters that construct the outlet instance. Given this, we can easily recreate the :class:`jotting.to.File` outlet: .. code-block:: python import os from jotting.to import outlet @outlet def File(log, path): path = os.path.realpath(os.path.expanduser(path)) with open(path, "a+") as f: f.write(log) or the :class:`jotting.to.Print` outlet: .. code-block:: python import sys from jotting.to import outlet @outlet def Print(log): """Send logs directly to ``sys.stdout``""" sys.stdout.write(log) sys.stdout.flush()