1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
Quickstart
==========
Let's see how easy it is to use Eliot.
Installing Eliot
----------------
To install Eliot and the other tools we'll use in this example, run the following in your shell:
.. code-block:: shell-session
$ pip install eliot eliot-tree requests
You can also install it using Conda:
.. code-block:: shell-session
$ conda install -c conda-forge eliot eliot-tree requests
This will install:
1. Eliot itself.
2. `eliot-tree <https://github.com/jonathanj/eliottree>`_, a tool that lets you visualize Eliot logs easily.
3. ``requests``, a HTTP client library we'll use in the example code below.
You don't need it for real Eliot usage, though.
Our example program
-------------------
We're going to add logging code to the following script, which checks if a list of links are valid URLs:
.. code-block:: python
import requests
def check_links(urls):
for url in urls:
try:
response = requests.get(url)
response.raise_for_status()
except Exception as e:
raise ValueError(str(e))
try:
check_links(["http://eliot.readthedocs.io", "http://nosuchurl"])
except ValueError:
print("Not all links were valid.")
Adding Eliot logging
--------------------
To add logging to this program, we do two things:
1. Tell Eliot to log messages to file called "linkcheck.log" by using ``eliot.to_file()``.
2. Create two actions using ``eliot.start_action()``.
Actions succeed when the ``eliot.start_action()`` context manager finishes successfully, and fail when an exception is raised.
.. literalinclude:: ../../examples/linkcheck.py
:emphasize-lines: 2,3,7,10
Running the code
----------------
Let's run the code:
.. code-block:: shell-session
$ python linkcheck.py
Not all the links were valid.
We can see the resulting log file is composed of JSON messages, one per line:
.. code-block:: shell-session
$ cat linkcheck.log
{"action_status": "started", "task_uuid": "b1cb58cf-2c2f-45c0-92b2-838ac00b20cc", "task_level": [1], "timestamp": 1509136967.2066844, "action_type": "check_links", "urls": ["http://eliot.readthedocs.io", "http://nosuchurl"]}
...
So far these logs seem similar to the output of regular logging systems: individual isolated messages.
But unlike those logging systems, Eliot produces logs that can be reconstructed into a tree, for example using the ``eliot-tree`` utility:
.. code-block:: shell-session
:emphasize-lines: 3,8,13,16-19,21-23
$ eliot-tree linkcheck.log
b1cb58cf-2c2f-45c0-92b2-838ac00b20cc
└── check_links/1 ⇒ started
├── timestamp: 2017-10-27 20:42:47.206684
├── urls:
│ ├── 0: http://eliot.readthedocs.io
│ └── 1: http://nosuchurl
├── download/2/1 ⇒ started
│ ├── timestamp: 2017-10-27 20:42:47.206933
│ ├── url: http://eliot.readthedocs.io
│ └── download/2/2 ⇒ succeeded
│ └── timestamp: 2017-10-27 20:42:47.439203
├── download/3/1 ⇒ started
│ ├── timestamp: 2017-10-27 20:42:47.439412
│ ├── url: http://nosuchurl
│ └── download/3/2 ⇒ failed
│ ├── errno: None
│ ├── exception: requests.exceptions.ConnectionError
│ ├── reason: HTTPConnectionPool(host='nosuchurl', port=80): Max retries exceeded with url: / (Caused by NewConnec…
│ └── timestamp: 2017-10-27 20:42:47.457133
└── check_links/4 ⇒ failed
├── exception: builtins.ValueError
├── reason: HTTPConnectionPool(host='nosuchurl', port=80): Max retries exceeded with url: / (Caused by NewConnec…
└── timestamp: 2017-10-27 20:42:47.457332
Notice how:
1. Eliot tells you which actions succeeded and which failed.
2. Failed actions record their exceptions.
3. You can see just from the logs that the ``check_links`` action caused the ``download`` action.
Next steps
----------
You can learn more by reading the rest of the documentation, including:
* The :doc:`motivation behind Eliot <introduction>`.
* How to generate :doc:`actions <generating/actions>`, :doc:`standalone messages <generating/messages>`, and :doc:`handle errors <generating/errors>`.
* How to integrate or migrate your :doc:`existing stdlib logging messages <generating/migrating>`.
* How to output logs :doc:`to a file or elsewhere <outputting/output>`.
* Using :doc:`asyncio or Trio coroutines <generating/asyncio>`, :doc:`threads and processes <generating/threads>`, or :doc:`Twisted <generating/twisted>`.
* Using Eliot for :doc:`scientific computing <scientific-computing>`.
|