Tracing¶
pjrpc
supports client and server metrics collection. If you familiar with
aiohttp library it won’t take a lot of time to comprehend
the metrics collection process, because pjrpc
inspired by it and uses the same patterns.
client¶
The following example illustrate opentracing integration. All you need is just inherit a special class
pjrpc.client.Tracer
and implement required methods:
import opentracing
from opentracing import tags
from pjrpc.client import tracer
from pjrpc.client.backend import requests as pjrpc_client
class ClientTracer(tracer.Tracer):
def __init__(self):
super().__init__()
self._tracer = opentracing.global_tracer()
async def on_request_begin(self, trace_context, request):
span = self._tracer.start_active_span(f'jsonrpc.{request.method}').span
span.set_tag(tags.COMPONENT, 'pjrpc.client')
span.set_tag(tags.SPAN_KIND, tags.SPAN_KIND_RPC_CLIENT)
async def on_request_end(self, trace_context, request, response):
span = self._tracer.active_span
span.set_tag(tags.ERROR, response.is_error)
if response.is_error:
span.set_tag('jsonrpc.error_code', response.error.code)
span.set_tag('jsonrpc.error_message', response.error.message)
span.finish()
async def on_error(self, trace_context, request, error):
span = self._tracer.active_span
span.set_tag(tags.ERROR, True)
span.finish()
client = pjrpc_client.Client(
'http://localhost/api/v1', tracers=(
ClientTracer(),
),
)
result = client.proxy.sum(1, 2)
server¶
On the server side you need to implement simple functions (middlewares) and pass them to the JSON-RPC application. The following example illustrate prometheus metrics collection:
import asyncio
import prometheus_client
from aiohttp import web
import pjrpc.server
from pjrpc.server.integration import aiohttp
method_latency_hist = prometheus_client.Histogram('method_latency', 'Method latency', labelnames=['method'])
method_active_count = prometheus_client.Gauge('method_active_count', 'Method active count', labelnames=['method'])
async def metrics(request):
return web.Response(body=prometheus_client.generate_latest())
http_app = web.Application()
http_app.add_routes([web.get('/metrics', metrics)])
methods = pjrpc.server.MethodRegistry()
@methods.add(context='context')
async def method(context):
print("method started")
await asyncio.sleep(1)
print("method finished")
async def latency_metric_middleware(request, context, handler):
with method_latency_hist.labels(method=request.method).time():
return await handler(request, context)
async def active_count_metric_middleware(request, context, handler):
with method_active_count.labels(method=request.method).track_inprogress():
return await handler(request, context)
jsonrpc_app = aiohttp.Application(
'/api/v1', app=http_app, middlewares=(
latency_metric_middleware,
active_count_metric_middleware,
),
)
jsonrpc_app.dispatcher.add_methods(methods)
if __name__ == "__main__":
web.run_app(jsonrpc_app.app, host='localhost', port=8080)