Package: eliot-tree
RenderEliotlogs as an ASCII tree.This output:(or as text)$eliot-treeeliot.logf3a32bb3-ea6b-457c-aa99-08a3d0491ab4└──app:soap:client:request/1⇒started2015-03-0304:28:56⧖1.238s├──dump:/home/user/dump_files/20150303/1425356936.28_Client_req.xml├──soapAction:a_soap_action├──uri:http://example.org/soap├──app:soap:client:success/2/1⇒started2015-03-0304:28:57⧖0.000s│└──app:soap:client:success/2/2⇒succeeded2015-03-0304:28:57│└──dump:/home/user/dump_files/20150303/1425356937.52_Client_res.xml└──app:soap:client:request/3⇒succeeded2015-03-0304:28:57└──status:20089a56df5-d808-4a7c-8526-e603aae2e2f2└──app:soap:service:request/1⇒started2015-03-0304:31:08⧖3.482s├──dump:/home/user/dump_files/20150303/1425357068.03_Service_req.xml├──soapAction:method├──uri:/endpoints/soap/method├──app:soap:service:success/2/1⇒started2015-03-0304:31:11⧖0.001s│└──app:soap:service:success/2/2⇒succeeded2015-03-0304:31:11│└──dump:/home/user/dump_files/20150303/1425357071.51_Service_res.xml└──app:soap:service:request/3⇒succeeded2015-03-0304:31:11└──status:200was generated from:{"dump":"/home/user/dump_files/20150303/1425356936.28_Client_req.xml","timestamp":1425356936.278875,"uri":"http://example.org/soap","action_status":"started","task_uuid":"f3a32bb3-ea6b-457c-aa99-08a3d0491ab4","action_type":"app:soap:client:request","soapAction":"a_soap_action","task_level":[1]}{"timestamp":1425356937.516579,"task_uuid":"f3a32bb3-ea6b-457c-aa99-08a3d0491ab4","action_type":"app:soap:client:success","action_status":"started","task_level":[2,1]}{"task_uuid":"f3a32bb3-ea6b-457c-aa99-08a3d0491ab4","action_type":"app:soap:client:success","dump":"/home/user/dump_files/20150303/1425356937.52_Client_res.xml","timestamp":1425356937.517077,"action_status":"succeeded","task_level":[2,2]}{"status":200,"task_uuid":"f3a32bb3-ea6b-457c-aa99-08a3d0491ab4","task_level":[3],"action_type":"app:soap:client:request","timestamp":1425356937.517161,"action_status":"succeeded"}{"dump":"/home/user/dump_files/20150303/1425357068.03_Service_req.xml","timestamp":1425357068.032091,"uri":"/endpoints/soap/method","action_status":"started","task_uuid":"89a56df5-d808-4a7c-8526-e603aae2e2f2","action_type":"app:soap:service:request","soapAction":"method","task_level":[1]}{"timestamp":1425357071.51233,"task_uuid":"89a56df5-d808-4a7c-8526-e603aae2e2f2","action_type":"app:soap:service:success","action_status":"started","task_level":[2,1]}{"task_uuid":"89a56df5-d808-4a7c-8526-e603aae2e2f2","action_type":"app:soap:service:success","dump":"/home/user/dump_files/20150303/1425357071.51_Service_res.xml","timestamp":1425357071.513453,"action_status":"succeeded","task_level":[2,2]}{"status":200,"task_uuid":"89a56df5-d808-4a7c-8526-e603aae2e2f2","task_level":[3],"action_type":"app:soap:service:request","timestamp":1425357071.513992,"action_status":"succeeded"}Command-line optionsConsult the output ofeliot-tree--helpto see a complete list of command-line
options.StreamingIt’s possible to pipe data into eliot-tree, from a tailed log for example, and
have it rendered incrementally. There is a caveat though: Trees are only
rendered once an end message—a success or failure status—for the tree’s root
action appears in the data.Selecting / filtering tasksBy task UUIDEntire task trees can be selected by UUID with the--task-uuid(-u)
command-line option.By start / end dateIndividual tasks can be selected based on their timestamp, use--startto
select tasks after an ISO8601 date-time, and--endto select tasks before an
ISO8601 date-time.By custom queryCustom task selection can be done with the--selectcommand-line option, the
syntax of which isJMESPath, and is applied to the original Eliot JSON
structures. Any data that appears within an Eliot task structure can be queried.
Only the matching tasks (and all of their children) will be displayed, the
parents of the task structure (bytask_uuid) will be elided.An important thing to note is that the query should be used as apredicate(it
should describe a boolean condition), not to narrow a JSON data structure, as
many of the examples on the JMESPath site illustrate. The reason for this is
that Eliot tasks are not stored as one large nested JSON structure, they are
instead many small structures that are linked together by metadata
(task_uuid), which is not a structure than JMESPath is ideally equipped to
query.The--selectargument can be supplied multiple times to mimic logical AND,
that is all--selectpredicates must pass in order for a task or node to be
selected.ExamplesSelect all tasks that contain aurikey, regardless of its value:--select'uri'Select all Eliot action tasks of typehttp_client:request:--select'action_type == `"http_client:request"`'Backquotes are used to represent raw JSON values in JMESPath,`500`is the
number 500,`"500"`is the string “500”.Select all tasks that have anhttp_statusof 401 or 500:--select'contains(`[401, 500]`, status)'Select all tasks that have anhttp_statusof 401 that were also made to auricontaining the text/criticalEndpoint:--select'http_status == `401`'\--select'uri && contains(uri, `"/criticalEndpoint"`)'Here--selectis passed twice to mimic a logical AND condition, it is also
possible to use the JMESPath&&operator. There is also a test for the
existence of theurikey to guard against calling thecontains()function with a null subject.See theJMESPath specificationfor more information.Programmatic usageimportjson,sysfromeliottreeimporttasks_from_iterable,render_tasks# Or `codecs.getwriter('utf-8')(sys.stdout).write` on Python 2.render_tasks(sys.stdout.write,tasks,colorize=True)Seehelp(render_tasks)andhelp(tasks_from_iterable)from a
Python REPL for more information.ConfigurationCommand-line options may have custom defaults specified by way of a config file.
The config file can be passed with the--configargument, or will be read from~/.config/eliot-tree/config.json. Seeconfig.example.jsonfor an
example.Use the--show-default-configcommand-line option to display the default
configuration, suitable for redirecting to a file. Use the--show-current-configcommand-line option to display the current effective
configuration.Theme overridesTheme colors can be overridden via thetheme_overrideskey in the config file.
The value of this key is itself a JSON object, each key is the name of a theme
color and each value is a JSON list. This list should contain three values:Foreground color, terminal color name or code; ornullfor the default color.Background color, terminal color name or code; ornullfor the default color.An optional array of color attribute names or codes; ornullfor the
default attribute.For example, to override theroottheme color to be bold magenta, and theproptheme color to be red:{"theme_overrides":{"root":["magenta",null,["bold"]],"prop_key":["red"]}}See_theme.pyfor theme color names and thecoloredPython package for
available color and attribute constants.ContributeSee <https://github.com/jonathanj/eliottree> for details.