An OpenTracing library for Foxx Microservices.
# In your foxx application root
npm install --save @recallgraph/foxx-tracer
See https://recallgraph.github.io/foxx-tracer/ for the full API documentation. A quickstart guide is given below.
Most tracing libraries in the nodeverse are asynchronous, and so do not work in the synchronous V8 runtime that ArangoDB uses to run its Foxx services. foxx-tracer bridges this gap by being a 100% synchronous, dedicated module built for the Foxx runtime.
As a result, it relies on a number of features only available in a Foxx environment. It also depends on a companion collector service which itself is a Foxx microservice. These dependencies make this module incompatible with Node.js and browser-based runtimes.
- Add foxx-tracer as a dependency of the service for which you want to enable tracing.
npm install --save @recallgraph/foxx-tracer
- In your service, before mounting any trace-enabled routes, you need to initialize the tracer, trace headers and middleware. This is best done in your service's startup script (usually
main.js
).const { utils: { setEndpointTraceHeaders, initTracer }, middleware } = require('foxx-tracer') // Initialize the tracer initTracer() // Use the tracing middleware for all endpoints. // You may also do this selectively for only those endpoints that you want to trace. module.context.use(middleware) // Create a router. const router = createRouter() /* Create a request handler endpoint using one of the router's several instance methods: const endpoint = router.[get|post|put|patch|delete|all|use](...) */ // Attach trace headers to the endpoint setEndpointTraceHeaders(endpoint)
- To wrap a function in a new span, use
attachSpan
.const { utils: { attachSpan } } = require('foxx-tracer') attachSpan(function() {}, 'opName', {/* options */}, onSuccess /* optional */, onError /* optional */)
- To instrument a db query (with query stats collection and reporting), use
instrumentedQuery
.const { utils: { instrumentedQuery } } = require('foxx-tracer') const query = aql.query(/* query */) const cursor = instrumentedQuery(query, 'queryName', {/* options */})
- To correctly propagate the current span context across transaction boundaries, use
executeTransaction
.const { utils: { executeTransaction } } = require('foxx-tracer') const result = executeTransaction({/* transaction specification */})
- To correctly propagate the current span context across task invocations, use
executeTask
.const { utils: { executeTask } } = require('foxx-tracer') executeTask({/* task options */})
-
Install the collector service and follow its setup instructions. Add any reporter plugins that you need.
-
In your application's settings, there is a param named
sampling-probability
. You can set this to a value between 0 and 1 (both inclusive) to tell the tracer how often to record a trace for incoming requests. For example, ifsampling-probability = 0.1
, then roughly 1 out of 10 requests will be traced.Regardless of this param's value, a trace can be force-recorded or force-suppressed using the
x-force-sample
header parameter. See Recording Traces for details. -
Finally, you need to assign the collector dependency so that foxx-tracer knows where to send the recorded traces. The
manifest.json
file should have adependencies
object containing the following:{ "dependencies": { "traceCollector": { "name": "@RecallGraph/foxx-tracer-collector", "version": "^0.0.5", "description": "Opentrace-compatible collector to send span records to.", "required": false, "multiple": false } } }
Optional: If, for some reason, you cannot name your dependency as
traceCollector
(in the unlikely case that it clashes with another dependency key), you can rename it to any other valid manifest key. But then, additional configuration is required to tell the tracer where to find the collector. Themanifest.json
should now have an additonal setting inconfiguration
, containing the following:{ "configuration": { "reporters-foxx": { "type": "json", "required": true, "default": { "collector": "customCollectorDependencyKey" }, "description": "Settings for the foxx reporter." } } }
For the endpoints to which the trace middleware was attached, there are 4 trace-specific headers available that can be used for the following:
- Propagate a running trace from the client to your application.
- Force the application to record or suppress a trace for the request, regardless of the
sampling-probability
setting.
See the Trace Header documentation for details.
To get a better idea of how to instrument your Foxx service using foxx-tracer, take a look at the source of the RecallGraph project.