eliottree
eliottree copied to clipboard
Add programatic usage example,
I don't understand the current example for programmatic usage from the readme.
I took a look at the cli code and ended up with this example.
yes... it uses private API
Free free to update it with the public api.
How can you programmatically stop the eliot logging and cause it to flush the log file?
An example for programatting streaming usage would be nice
Good point! It looks like this example has been missing a line since forever, oops!
I'm hesitant to expose the private parsing APIs eliottree uses internally for it own ends (like building the whole inventory in order to better report errors, etc.). The example should look something like this:
import json, sys
from eliottree import tasks_from_iterable, render_tasks
with open('eliot.log', 'rb') as fd:
tasks = tasks_from_iterable(json.loads(line) for line in fd)
# Or `codecs.getwriter('utf-8')(sys.stdout).write` on Python 2.
render_tasks(sys.stdout.write, tasks, colorize=True)
How can you programmatically stop the eliot logging and cause it to flush the log file?
That seems like an eliot question more than an eliottree question, all eliottree wants is an iterable of tasks to render.
An example for programatting streaming usage would be nice
The above example is suitable for streaming usage, tasks_from_iterable
is itself a generator and it is being passed a generator.
Of course tasks_from_iterable
is exhausting all of its input and render_tasks
is blocking (on calling write
for all the tasks) but you can mitigate that by islicing the result of tasks_from_iterable
(tasks_from_iterable
only yields completely parsed eliot task trees) and calling render_tasks
cooperatively. Feed a generator, of parsed JSON, you can control the flow of to tasks_from_iterable
.
Although, looking at tasks_from_iterable
now, it will always yield all incomplete tasks after exhausting its iterable, which might not be what you want if you have a continually streaming iterable (from a network source, for example). So probably tasks_from_iterable
should have a way for a caller to control that.
@adiroiban Maybe if you can give me an idea of what your plan for streaming is (for example, is it from a file to a web browser via websocket?) we can see if there's an example that's not super complex.
I am new to eliot.... but I have this code https://github.com/twisted/txacme/blob/151-acme-v2/docs/client_example.py#L123
Instead of to_file(open(LOG_PATH, 'w'))
I and then later with open('eliot.log', 'rb') as fd:
I would like to be able to connect eliot output/collector directly to eliotree and have the output as fast as possible ... I understand that sometimes I might need to wait for the context to exit ... but that is fine
Feel free to close this PR and merge your version as a drive by. I just wanted to report this error ...and I know that your solution is better. no need to expose the private api.
Thanks!
I use this little snippet to render complete eliot tasks as they roll in:
from eliot import add_destinations
from eliot.parse import Parser
from eliottree import render_tasks
class EliotTreeDestination:
def __init__(self, out=sys.stdout.write, **opts):
self.out = out
self.opts = opts
self._parser = Parser()
def __call__(self, message):
tasks, self._parser = self._parser.add(message)
if tasks:
render_tasks(self.out, tasks, **self.opts)
add_destinations(EliotTreeDestination(colorize=True, colorize_tree=True, human_readable=True))
Thanks. That looks ok.
My suggestion is to make this a public/upstream API.
Maybe name it to_file
... similar to from eliot import to_file
, we can have from eliottree import to_file
.
What do you think?