Yes, there is few hooks that you can use to to build a distributed tracer.
Look here for the list of hooks on a zerorpc context:
https://github.com/dotcloud/zerorpc-python/blob/master/zerorpc/context.py
You can of course add middlewares to the default context: context.get_instance()
To register a middleware, call context.register_middleware(my_middleware)
A middleware is a simple object, with a bunch of method corresponding
to the different hooks you are interesting in.
Here the simplest example to build a tracer I can think of (untested):
import uuid
import zerorpc
import gevent.local
class MyTracerIDInjector(object): # Ensure that a probably unique
'trace_id' is available for the current task_context
locals = gevent.local.local()
def current_task_trace_id(self):
trace_id = self.locals.get('trace_id')
if trace_id: # we got a trace_id for the current task, so we go
along and use it
return trace_id
trace_id = uuid.uuid4().hex # we assume the beginning of a new trace
self.locals.trace_id = trace_id
return trace_id
def load_task_context(self, task_context):
# called when a new task is spawned on a server (because of a
new a new request)
# or called when forking a task with the result from a previous
get_task_context
trace_id = task_context.get('trace_id')
if trace_id:
self.locals.trace_id = trace_id
def get_task_context(self):
# return existing or create a new trace id
# called to inject the current task context in the event header
before sending it
# or called when forking a task, to copy the context in the new task
return {'trace_id': self.current_task_trace_id()}
class MyTracer(object): # Report traces!
def client_before_request(self, event):
trace_id = event.header.get('trace_id')
# here you can report to your central tracer service before the
event is sent to the server
def client_after_request(self, request_event, reply_event, exception):
trace_id = reply_event.header.get('trace_id')
# here you can report to your central tracer service after
receiving the event from the server (exception is not None if the
client is about to raise an exception)
def server_before_exec(self, request_event):
trace_id = request_event.header.get('trace_id')
# here you can report to your central tracer service after
receiving a new request from the client, before executing the method
on the server
def server_after_exec(self, request_event, reply_event):
trace_id = request_event.header.get('trace_id')
# here you can report to your central tracer service after a
successful execution of a method, before the event is sent to the
client
def server_inspect_exception(self, request_event, reply_event, exc_infos):
trace_id = reply_event.header.get('trace_id')
# here you can report to your central tracer service when an
exception occurred during the execution of a method on the server.
ctx = zerorpc.Context.get_instance()
ctx.register_middlware(MyTracerIDInjector())
ctx.register_middlware(MyTracer())
You do not have to split the tracer in two classes like I did, but
this shows the clear separation between the injection of the task_id
in the local task (ie: coroutine or greenlet) and the reporting of the
traces.
You need both MyTracerIdInjector and MyTracer to be registered on all
your zerorpc programs, in order to get a perfect tracing of all the
calls across your network of zerorpc nodes.
Best,
fx
> --
> You received this message because you are subscribed to the Google Groups
> "zerorpc" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to
zerorpc+u...@googlegroups.com.
> To post to this group, send email to
zer...@googlegroups.com.
> To view this discussion on the web visit
>
https://groups.google.com/d/msgid/zerorpc/02ce4b86-5f63-42e5-8f2a-c01d22b5158c%40googlegroups.com.
> For more options, visit
https://groups.google.com/d/optout.