We do tracing with Jaeger. You need to run a local image of it on your machine to be able to trace your work and make sure it's the behavior that would be helpful in debugging.
Tracing has two things:
The way this work is you find a root cause for a certain event e.g. endpoint, then create a context and pass it down all the functions being called by this endpoint (ignore trivial functions like validation and focus more on asynchronous operations).
Using a context
await ctx.execute(async ({ span, logger }) => {
// you can use logger returned from this
logger.info("some logging information", { hello: "you can pass data here" });
// you can also set tags here that show in Jaeger and allow for searching
span.setTag("retires", 2);
// you always need to have this in the end of every function
// that uses contexts
logger.success("a message is optional", {
some_data: "this is optional too"
});
});
Creating Context for an Endpoint
Call this function to create a context, pass it a name (what the endpoint does) and the req object.
create_endpoint_context("verify phone start", req);
<aside>
⛔ For endpoints that receive sensitive information e.g. passwords and login, you can pass a third argument data that has the data you want to get from req.body
</aside>
Creating Child Context
All the functions that do asynchronous operations must have a _ctx as the first parameter
function send_email(_ctx, { ... }) {
// do some work
}
To chain spans together so we can track each function and what it does, we need to create a context based on pass context _ctx
const ctx = create_context({
name: "<name of function or what it does>",
tags: {
email, // you can set searchable tags here
},
// pass it the context you got passed down
// if its' null then a new one will be created
root_context: _ctx,
});