Skip to content
This repository has been archived by the owner on Apr 17, 2019. It is now read-only.
/ remitrace Public archive

Adds tracing in the form of persistent IDs to nested remit requests.

License

Notifications You must be signed in to change notification settings

jpwilliams/remitrace

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Remit supports the OpenTracing standard from v2.4.0. It is highly recommended that you use v2.4.0 or above for any tracing requirements and disregard this library.

remitrace

Utilises the tracing metadata available in remit >=2.2.0 to push captured messages to a queue (or to custom loggers) for storage and correlation.

yarn add remitrace
const { remitrace } = require('remitrace')
const remit = require('remit')()
remitrace(remit)

See remitrace-mongo for a practical example of its use.


It's a nice, simple function:

remitrace(remit, options)

  • remit A running remit instance of version >=2.2.0
  • options An optional object containing a few options for remitrace:
    • queueName The RabbitMQ topic that remitrace will emit to. Defaults to 'remitrace'.
    • customLoggers Any custom actions to be done with traces can be specified as functions in an array here which are passed the event of the action to be traced. Defaults to []. [console.log] is a nice way to see the traces being logged.
    • ignoredPaths Event names to ignore when tracing messages. Must be an array of regexes. Defaults to [/^queueName$/] where queueName is the option above.

Tracing with remitrace

remitrace on its own only allows the easy capture of the data needed to trace your calls. There is, however, a usable MongoDB-backed example over at [remitrace-mongo]. For clarity, I'll explain how it works here too.

remit >=2.2.0 provides some new metadata intended for tracing inside each event in a new metadata object.

  • originId The ID of the initial request or emission that started the entire chain of calls. Every call in a chain will have the same ID here.
  • bubbleId The "bubble" (see more below) that the action happened in.
  • fromBubbleId The "bubble" (see more below) that the action was triggered from.
  • instanceId A unique ID for each and every action.
  • flowType Either 'entry' to show it's an entrypoint to a bubble, 'exit' to show it's an exit from a bubble or blank to show it is neither.

These five properties can be used to create a picture of not only how particular calls are triggered, but the effect that a single call can have on an entire system, accessible from any point.

What's a bubble?

A bubble, in this context, is represented as all remit-related actions performed within a handler for an endpoint or listener.

A bubble is created whenever a request or emission is received by an endpoint or listener. This is an 'entry' (as dictated by the flowType metadata). 'exit's are the requests or emissions themselves.

How does the information correlate?

We'll assume for this section that all traces are stored as-is within a simple document store such as MongoDB.

First off, you can easily find all messages created from a single originId by just querying for exactly that:

{
  "originId": "01C31N0NMCMS5KX8E4GJ6BV0G2"
}

With that, you could list every single action that happened because of that origin message.

You can also, however, get a little better.

A more common practice would be to seek out the cause of a particular event. A listener is receiving an emission, let's say, but you don't know why or where from. Following it through a complex production system would be horrendous, but with remitrace it's easily possible.

As above, an instanceId is a unique ID given to every action. Using this along with flowType's entries and exits, we can easily find the direct route from cause to effect.

Find the trace of the instanceId you wish to track. If it's an entry point, you must find the exit that lead to it. If it's not an entry, find the entry. An example in code:

async function findCause (query, traces = []) {
  // handle the initial sending of an instanceId
  if (typeof query === 'string') {
    query = { 'event.metadata.instanceId': query }
  }

  // find a trace and return early if it's the end of the line
  const nextTrace = await myCol.findOne(query)
  if (!nextTrace) return traces
  traces.push(nextTrace)
  if (!nextTrace.event.metadata.bubbleId) return traces

  // sort out what to search for next
  const nextQuery = nextTrace.event.metadata.flowType === 'entry' ? {
    'event.metadata.flowType': 'exit',
    'event.metadata.bubbleId': nextTrace.event.metadata.fromBubbleId,
    'event.eventId': nextTrace.event.eventId
  } : {
    'event.metadata.flowType': 'entry',
    'event.metadata.bubbleId': nextTrace.event.metadata.bubbleId
  }

  // go search for it
  return findCause(nextQuery, traces)
}

const traces = await findCause('01C31NWW065X38YPBGJTZXAHVV')

The result of this would be a list of traces which lead to the specified action.

About

Adds tracing in the form of persistent IDs to nested remit requests.

Resources

License

Stars

Watchers

Forks

Packages

No packages published